LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

-0.002 and -0.002 are not equal

Solved!
Go to solution

BTW, I have seen seen situations where a difference was expected to be 0 but was in fact 2 epsilon.

 

Of course the difference can be much bigger if the calculation isn't done carefully.

 

For instance:

(Big_number + Tiny_number ) / 3 - Big_number / 3

could be very different from

Big_number /3  - Big_number / 3 + Tiny_number / 3

Or

(Big_number - Big_number) / 3 + Tiny_number / 3

Or just

Tiny_number / 3

 

0 Kudos
Message 21 of 29
(288 Views)

@maxnoder1995 wrote:

How can I use this function? Can you please attach a VI file that I can open?


Wiebe posted a snippet. Download the image and drop it onto a block diagram you should have the primitive.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 22 of 29
(283 Views)

@crossrulz wrote:

@maxnoder1995 wrote:

How can I use this function? Can you please attach a VI file that I can open?


Wiebe posted a snippet. Download the image and drop it onto a block diagram you should have the primitive.


It is sometimes not so easy on NI Forum to download NI Snippet generated from NI LabVIEW, but possible — refer to Resolve links to VI snippets.

0 Kudos
Message 23 of 29
(280 Views)

@Andrey_Dmitriev wrote:

@crossrulz wrote:

@maxnoder1995 wrote:

How can I use this function? Can you please attach a VI file that I can open?


Wiebe posted a snippet. Download the image and drop it onto a block diagram you should have the primitive.


It is sometimes not so easy on NI Forum to download NI Snippet generated from NI LabVIEW, but possible — refer to Resolve links to VI snippets.


True. One of the reasons I attach the image to my posts. Speaking of which, I am attaching Wiebe's snippet here to make life a little easier for somebody.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 24 of 29
(273 Views)

wiebe@CARYA wrote:

 

 

Of course the difference can be much bigger if the calculation isn't done carefully.

 

For instance:

(Big_number + Tiny_number ) / 3 - Big_number / 3

could be very different from

Big_number /3  - Big_number / 3 + Tiny_number / 3

Or

(Big_number - Big_number) / 3 + Tiny_number / 3

Or just

Tiny_number / 3

 


Yes, of course, this is how IEEE 754 works. Technically we mapping "continuous" range of floats (doubles) to the discrete scale (because we have only 32 bits for floats and 64 bits for doubles). And the step is variable - very small for small numbers and larger and larger for large. For the large doubles the last one which have exact integer representation is 9007199254740992. There is no 9007199254740993 number exists. The next one is 9007199254740994, from this point the representable numbers are the only even ones and so on. Below 4503599627370496 the spacing is 0.5, then gets smaller.

 

Especially for the example with 0.1 0.2 and 0.3. When the user enters 0.1, then exact number which is really entered is 0.1000000000000000055511151231257827021181583404541015625. When 0.2 entered to the constant, then exact number is 0.200000000000000011102230246251565404236316680908203125.

 

There are no exact representation for 0.1 and 0.2, the next smaller numbers below 0.1 and 0.2 on the scale are 0.09999999999999999167332731531132594682276248931884765625 and 0.1999999999999999833466546306226518936455249786376953125, which are slightly more away from "true" values.

 

And for the constant 0.3 the exact closest number is 0.299999999999999988897769753748434595763683319091796875. But when both 0.1 and 0.2 added together, then result is next available number which is 0.3000000000000000444089209850062616169452667236328125. And this is why comparison not work. And there are no numbers between 0.299999999999999988897769753748434595763683319091796875 and 0.3000000000000000444089209850062616169452667236328125 are possible at all. LabVIEW will show it like this:

rounds.png

0 Kudos
Message 25 of 29
(270 Views)

@Andrey_Dmitriev wrote:

@crossrulz wrote:

@maxnoder1995 wrote:

How can I use this function? Can you please attach a VI file that I can open?


Wiebe posted a snippet. Download the image and drop it onto a block diagram you should have the primitive.


It is sometimes not so easy on NI Forum to download NI Snippet generated from NI LabVIEW, but possible — refer to Resolve links to VI snippets.


Click the image then this button:

wiebeCARYA_0-1732199719125.png

Seems to always work for me.

Message 26 of 29
(273 Views)

wiebe@CARYA wrote:

Click the image then this button:

wiebeCARYA_0-1732199719125.png

Seems to always work for me.


Good point, seems to be OK. I always downloaded snippets by ID before. But in ideal case it should be possible to drag and drop directly from browser. It works if "native" image linked, but NI does "previewing" and this breaks snippets, because custom data gets removed from PNG.

0 Kudos
Message 27 of 29
(264 Views)

@Andrey_Dmitriev wrote:

wiebe@CARYA wrote:

Of course the difference can be much bigger if the calculation isn't done carefully.

 

For instance:

(Big_number + Tiny_number ) / 3 - Big_number / 3

could be very different from

Big_number /3  - Big_number / 3 + Tiny_number / 3

Or

(Big_number - Big_number) / 3 + Tiny_number / 3

Or just

Tiny_number / 3


Yes, of course, this is how IEEE 754 works.


It is. It can be a real problem though.

 

For instance the average value of 1E24, 3 and -1E24 is 0, while the average of 1E24, -1E24 and 3 is 1.

wiebeCARYA_1-1732200204017.png

 

A solution is to always sort on exponent, or on absolute value, before adding the values...

 

An old performance trick (also used by Mean PtByPt.vi) to saving averaging calculation time by keeping the sum and a history of values in a circular buffer, adding new values, subtracting the oldest value does work in theory, but not always* in practice. It does save a potential expensive calculation of the sum of all values each iteration, but values will be incorrect if they have a large range. And once the sum is incorrect, it takes a while to recover. Of course, once a NaN is added it will never recover...

 

* If the data comes from a AI, you're probably safe. Both the value range and resolution are limited...

0 Kudos
Message 28 of 29
(256 Views)

wiebe@CARYA wrote:

It is. It can be a real problem though.

 

For instance the average value of 1E24, 3 and -1E24 is 0, while the average of 1E24, -1E24 and 3 is 1.

wiebeCARYA_1-1732200204017.png

 

 

 


Oh, yes, operations on doubles are not commutative in general, so a + b + c could be not equal to a + c + b, it is quite easy to demonstrate also on small numbers:

comm.png

0 Kudos
Message 29 of 29
(238 Views)