"be consistent" PerlMonks

### Re^2: False positive on inequality comparison

by Nkuvu (Priest)
 on Apr 03, 2009 at 22:21 UTC ( #755354=note: print w/replies, xml ) Need Help??

I appreciate the idea, but... still confused. I've changed the code to the following:

```my \$tolerance = 1.0e-16; # Change this value based on observation

if (\$tolerance*abs(\$range_min + \$change_min) < abs(\$range_min - \$chang
+e_min)) {
print "\$variable has different minimum value:\n";
print "  Change list: \$changes{\$variable}{min} (\$changes{\$variable
+}{sheet})\n";
print "  Range file : \$range_file{\$variable}{min} (\$range_file{\$va
+riable}{sheet})\n";
my \$difference = \$range_min - \$change_min;
printf "  Difference : %0.24f\n", \$difference;
}

if (\$tolerance*abs(\$range_max + \$change_max) < abs(\$range_max - \$chang
+e_max)) {
print "\$variable has different maximum value:\n";
print "  Change list: \$changes{\$variable}{max} (\$changes{\$variable
+}{sheet})\n";
print "  Range file : \$range_file{\$variable}{max} (\$range_file{\$va
+riable}{sheet})\n";
my \$difference = \$range_min - \$change_min;
printf "  Difference : %0.24f\n", \$difference;
}

Only difference to what you posted is the printf rather than print. And that was because the difference being shown with print was zero. This change in the code eliminated differences for four of the seven variables, but three remain:

```variable_c has different maximum value:
Change list: 45142.388774415 (Intermediate Variables)
Range file : 45142.388774415 (Intermediate Variables)
Difference : -0.000000000000014210854715
variable_f has different maximum value:
Change list: 181.019658002611 (Intermediate Variables)
Range file : 181.019658002611 (Intermediate Variables)
Difference : 0.000000000000000000000000
variable_g has different maximum value:
Change list: 1.57615706403821 (Intermediate Variables)
Range file : 1.57615706403821 (Intermediate Variables)
Difference : 0.000000000000000000000000

Variable C makes some sort of sense. I mean, I'm still under the impression that if I assign 45142.388774415 directly to two different variables, they should both have the same floating point representation. But they don't, obviously.

But what the hork is up with the other two? It seems to me that if the tolerance is 1e-16, there should be some difference shown in 24 places in the floating point number.

Replies are listed 'Best First'.
Re^3: False positive on inequality comparison
by BrowserUk (Pope) on Apr 04, 2009 at 02:07 UTC

Can I suggest that you dump each value to a file along with some natural identifier (line number or cell ID), using:

```print unpack 'b64', pack 'd', \$float;;
1011110110001011101100101110110101100111111000110111101000000011

Do this immediately after reading it into your script to ensure the minimum possibility of 'internal influences'. Then, when you encounter unexpected/unexplainable differences, dump both values in the same form, along with their original identifiers.

I can't offer an explanation for how or why what you are seeing could happen, but I have seen some weirdness in Perl's internal handling of floats in the past. Dumping bit patterns is surest way I know of inspecting what is actually there.

That said, you can still be fooled, as IEEE allow for the possibility of denormalised representations. That is, the bit patterns can be different but represent (exactly) the same values. Kind of like binary equivalent of 10e-6 vs. 1e-5.

Anyway, if you can track what differences are being perceived, then you may be able to backtrack to where they arise. And if you can do that, an explanation of why may be obvious or forthcoming.

Good luck.

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

For the record, I did try this as well, but it didn't help my Monday morning mind narrow anything down. Specifically, I found the same three differences. The binary representations didn't change between the time I read the values in and the time I compared them.

First two lines are reading files in from Excel sheets, second two are later in the script when the difference is found. I didn't include all three differences here, since they're all the same scenario. Different values read in from the files, no change to those values for the comparison:

```read var_f in from change file: 10011100010100111000101110010000100001
+01000001010110011000000010
read var_f in from range file : 10101100010100111000101110010000100001
+01000001010110011000000010
var_f value in change hash    : 10011100010100111000101110010000100001
+01000001010110011000000010
var_f value in range hash     : 10101100010100111000101110010000100001
+01000001010110011000000010

I'm not familiar enough with floating point representation to say what the difference is (it's been years since I had to convert a binary to float, and unfortunately need to do actual work this morning rather than brush up on the process). I think this is a difference in exponents, but that wouldn't make a lot of sense to me with the rest of the binary value being identical.

Hm. When I unpack those two values, they are distinctly different:

```printf "%17.17f\n", unpack 'd', pack 'b64',
'1001110001010011100010111001000010000101000001010110011000000010';;
181.01965800261112000

printf "%17.17f\n", unpack 'd', pack 'b64',
'1010110001010011100010111001000010000101000001010110011000000010';;
181.01965800261101000

\$first = unpack 'd', pack 'b64',
'1001110001010011100010111001000010000101000001010110011000000010';;

\$second = unpack 'd', pack 'b64',
'1010110001010011100010111001000010000101000001010110011000000010';;

printf "%f %f ;> %17.17f\n", \$first, \$second, \$first - \$second;;
181.019658 181.019658 ;> 0.00000000000011369

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Create A New User
Node Status?
node history
Node Type: note [id://755354]
help
Chatterbox?
 Discipulus second time; no questions.. o tempora o mores.. [1nickt]: I understood the first version ;-)

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (9)
As of 2017-11-24 22:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
In order to be able to say "I know Perl", you must have:

Results (354 votes). Check out past polls.

Notices?