From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Issue with "Less" Function in LabVIEW 2015

Solved!
Go to solution

Hi Guys,

 

I'm creating a VI that will allow me to log data at time intervals of .1, .2, .3, .4, .5, .6, .7, .8, .9, 1, 2, 3, 4 etc seconds or 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30 etc seconds depending on my input from my main VI.

 

In the VI I have attached I have a Hold Down case and a Toggle case. I've gone through the Hold Down case with highlight execution and it seems to be ok. My problems start when using the Toggle case. If I initiate the Stress Time In control at 0, it increments to .1, .2, .3, .4, .5, .6, .7, .8 .9 and 1 as expected. However, when transitioning from adding .1 into the case structure where it is supposed to start adding 1's, it ends up adding a .1 and a 1 for the first time and then continues to add 1 as expected. I've traced it back  in the code and when I turn on highlight execution with a 1 coming from the shift register, it is input into the "Less than" function in the bottom case structure and it outputs a True when it should output a False. My top case structure also outputs a zero when it should start outputting 1.

 

Can someone please run this code and see if the problem exists for them to preserve my sanity? Or am I just being an idiot and missing something obvious because of a crossed wire or something?

 

Thanks for your help

 

 

Download All
0 Kudos
Message 1 of 16
(3,827 Views)

From the sounds of it, the problem is to do with DBL floating point comparisons. The way that a DBL represents 1 is the best approximation it can store in 32-bits. It isn't necessarily exactly 1.0...it might be stored as 1.000000000000000000000000001. If you change the display precision to a really high number of decimal places, you'll see the tiny difference in the values and it will make sense as to why the result of the comparison isn't what you're expecting.

 

You also have to be really careful when checking if a DBL 0 is equal to 0. It might be 0 at first glance, but it could also be -0 or 0.0000000000000000000001


LabVIEW Champion, CLA, CLED, CTD
(blog)
Message 2 of 16
(3,811 Views)
Message 3 of 16
(3,792 Views)

Hi Guys,

 

Thank you for the responses. I've gone through the links posted above and have read through the proposed solutions. Is there any easier way that I could just reduce the precision of the floating point to just a few digits? If I understand correctly, I can't use integers because my values aren't whole numbers to begin with. Or is it better to just use the range and coerce function to make the code work? Thank you.

 

 

0 Kudos
Message 4 of 16
(3,765 Views)
After the decimal if you know exactly how many digits(z) it will be you can multiply both x and y with 10^z and then check with less than function.
Thanks
uday
Message 5 of 16
(3,759 Views)
Solution
Accepted by topic author GavinSheehan

You basically have several choices:

  • make the Floats an "exact" (=integer) value (say, by multiplying by 10 and changing the result to I32, the last step being necessary because only Integer representation allows exact numeric comparisons
  • make the Floats strings with a defined precision
  • write (and use) a "almost equal" function (subtract the value you are testing from the float, take absolute value, and see if <0.0001, or whatever precision you need.

Of these, the last is likely to be (by far) the fastest, and will "remind" you that fractional values are typically "approximations" (you can represent 0.5, 0.25, 0.125, etc. exactly, but not 0.1, for example).

 

Bob Schor

Message 6 of 16
(3,758 Views)

Multiplied both by 10 and its working correctly now! Thank you everyone!

0 Kudos
Message 7 of 16
(3,747 Views)

Here's an old post by Altenbach that shows a way to perform an Almost Equal on doubles by ignoring some amount of bit tolerance.

 

http://forums.ni.com/t5/LabVIEW/How-to-measure-LSBits-of-difference-between-floats-if-possible/m-p/3...

0 Kudos
Message 8 of 16
(3,742 Views)

(Sorry, I am a bit late to the party because I am on the west coast, but here are my thoughts).

 

Yes, The core reason for your observation is the limitations of DBL representation, but I think you are looking in the wrong place. Your code is just a plain monstrosity and I am sure that your problem can be solved with 5% of the code you currently have. Try to find a more elegant way to do all this. Having dozens of case structure and add primitives cannot be the solution.

As a first step, explain what the output as a function of input should be. What is the range of allowed inputs (e.g. can it be negative?).

As a second step, modify the code so we can actually test it. Currently your code gets trapped in the while loop and no output is ever produced because the loops will run forever. This cannot be right!

To do range checking, it is typcailly easiest to threshold the input value into an array of boundaries.

Also having clean code is a big step towards readability. It is very difficult to follow all these crisscrossing wires and the jumble of randomly placed comparison and boolean operations. Also stick to one datatype, you have many coercion dots for no good reason at all. You have several diagram constants with the same value. One each is enough, just branch the wire!

 

In any case, please tell us what the two cases are supposed to output as a function of the input. Maybe even a simple graph or table of some representative  "stress time out" vs "stress time in".

 

I think you are digging yourself into a hole here and  multiplying by 10 is just a bandaid that needs to be ripped of and replaced once you need to adapt the code to deal with e.g. 0.01 second increments. Instead of actually fixing the problem, you just sweep it under the rug.

Message 9 of 16
(3,731 Views)

Hi,

 

Thank you for the reply. This VI is a sub-VI in a VI which does data collection and logs it against the stress time. I had the stop condition set to false while I was testing so that I wouldn't have to go in and out of the main VI to see what was happening when I was using highlight execution.In use within the main VI, this VI's stop condition is set to True and I have the shift registers connected to my While loop of my main VI. Apologies but I cannot send on the code of my main VI.

 

I'm making the code for a colleague and we will never have to measure below an interval of .1 seconds or above 10000 seconds so I wrote the code with those limits in mind.

 

Apologies for the messy code. I'm usually a stickler for having clean readable code but that went out the window for this time measuring VI. I guess some background to the function of the code is as follows: I have 2 possible types of experiment, Hold Down and Toggle. I want my Toggle test to initially log more frequent values than the equivalent Hold Down test but after 1 second has elapsed, they are both able to be the same interval.

 

So in my main VI with a Toggle experiment selected, I want to measure @t0, wait for .1 seconds, measure, wait .1 seconds etc until 1 second of total experimental time has elapsed. When 1 second has elapsed I want to measure, wait for 1 second, measure, and wait for 1 second etc etc until the total experimental time is 10 seconds. When 10 seconds has elapsed I want to measure, wait for 10 seconds, measure, and wait for 10 seconds etc etc until the total experimental time is 100 seconds. And I keep doing this until I get to 10000 second intervals between measurements and when this point is reached, a constant measurement interval of 10000 seconds is output from the loop.

 

If I select a Hold Down test, my code performs the same function but it cuts out the intervals from 0-1 second and jumps straight to 1 second intervals.

 

I'd love to hear ways to improve and alter this because I spent a loooong time trying to figure out a way to do it to suit my needs.

0 Kudos
Message 10 of 16
(3,709 Views)