I am starting this thread as a repository for little-known facts, tidbits, and minutiae about LabVIEW that may eventually bite you if you are not aware of the behavior. Feel free to present these in any way you see fit: as a riddle, as a puzzle, as a mini-nugget, as a direct link to some other conversation....
(I am not aware of a thread currently serving this purpose, but if there is I will promptly consider this one shut down and post there.)
The first Bit of Minutiae will be presented as a challenge: using the attached VI (source code image shown), produce the following output where the two DBL's are equal to each other, but their flattened values are not equal to each other.
Tell me the values that yield this result:
Hints: #1 I can only find one reference to the solution on forums.ni.com, and #2 This bit of minutiae is much more of a "biter" in 8.6.1 and previous as compared to 2009 and beyond due to a change between these versions.
0 and -0
I'm not sure how you would come across this situation that it would wind up biting. I can only think if someone happens to enter -0 in a control. Or somehow you do some bit or byte manipulations that you wind up typecasting to a double. (Single and Ext representations do the same thing.)
(Interesting side note: NaN and NaN are not equal to each other, but their flattened values are.)
Ravens is right! His words "I'm not sure how you would come across this situation that it would wind up biting" were my sentiments exactly.... until it bit us.
Here's the scenario: we get flattened data over a network protocol, then unflatten the data to compare datasets. EVERY SO OFTEN, packets would come across where the checksum (which is calculated from the flattened data string) would not match the checksum of our reference dataset, but the unflattened data would be "equal to" the reference. It ended up boiling down to 0=-0, but not true for the flattened values.
Another bit of surprising info is that 0 is not greater than -0. Try feeding those two numbers, and then swapping them, into the "Max & Min" primitive.
And you can get -0 from a calculation, it's not just from an "accidental" user input: take a very very small negative number, and divide it by a very very large positive number. The result is -0.
So just be aware, two "equal" datasets can have two different checksums since their flattened values are not equal. Prior to LV2009, both simply displayed as "0", but since then the numeric displays have been appropriately portrayed as "0" and "-0". (This would have alleviated my colleague's stress in tracking down the bug in 8.6.1 a few months ago)
Here's the one link on the forums about The representation of negative zero.
The next bit of minutiae is probably much more well-known to the experienced LabVIEW users, but it is much more common: feeding references through For Loops.
It's very common to autoindex For Loops, but sometimes the autoindexing array will have zero elements. This causes the For Loop to run 0 times, and will return a NULL reference for any reference that uses tunnels through the For Loop. Instead, use shift registers for references. This guarantees that the same reference is returned on the output of the For Loop that was fed into the input, regardless of how many times the loop runs (given, no parallel process changed the reference!).
Some conversation here, after which LabBEAN provides four links to other forum posts dealing with shifting refs. The code below will execute properly for the top For Loop, but the bottom example will throw an error on the property node since it is receiving a NULL reference.
Also there are some arithmetic inconsistencies...
LabVIEW, C'est LabVIEW
Thanks, JeanPierre, I never knew that! Glad I know before it had a chance to bite me!
There's another similar trick that JeanPierre reminded me of, and that is the behavior of incrementing enums. They are circular, resetting back to the first element once you increment the maximum enum value. This is commonly used as a feature (e.g. looping state machines), but can just as easily produce puzzling results if you didn't originally design for the circular nature.
Below is a chart of how enums/U8's behave to both the "Increment" primitive and the "Expression Node"
I got an e-mail from one of developers on-site last week asking why one node executes and and another did not.
LV is smart enough to "see" tht the data returned by a property/invoke node or sub-VI is not used and will compile it out.
Adding an "Index array" to the "Equip" output of the top node was enough to get LV to execute that node.
... why one node executes and and another did not.
Here's a pretty obvious one.
What's the value of the numeric such that the result of the following code produces a FALSE? 😄
[Aside: NaN will not display on graphs, which can be useful when you want a "break" in the plot (e.g. limit lines, etc.)]