One of my co-workers, a Clipper-programmer, ran into a really weird bug/problem in a billing-program he wrote, after he received a complaint from one of the customers.

The software does some calculations based on orders, and generates and prints a bill automatically.
Because of strict coding-rules every single result of the calculation is declared integer.
All goes well, until the result of the calculation becomes '1645'.
When the number '1645' (without decimals) is declared integer, it returns '1644' !

First we thought it was a coding-problem, and tried several combinations of numbers to check if the formula used is not buggy. After running several tests the formula was found to be OK, but, the problem occurs again with this 'magic' number 1645.

To test if the bug is not in the Clipper-compiler, we tried the same thing with a simple PHP script, on a different PC.
And again : when 1645 is declared integer, it returns 1644...
Since both PC's have an Intel Pentium processor, we thought it could be a kind of overflow-bug in the Pentium instruction-set, so we tried the same on a PC with an AMD processor.
And again, in the PHP-script running on an AMD based PC this time, we declare 1645 as integer, and it returns, you can already guess, 1644 !?!

So it cannot be a bug in the Intel or AMD chipset, nor in the Clipper compiler, nor in PHP.

To test this problem we used following PHP-code, using the exact same calculation that generated the errornous number :

<?php
$x = 2516.70;
$y = 871.70;
$z = $x - $y; 

echo "\$x = ".$x." ; \$y = ".$y."<br>";
echo "\$z = \$x - \$y = ".$z."<br>";

settype ($z ,"integer");
echo "\$z as integer becomes ".$z."<br>";
?>

The result of $x minus $y becomes $z (1645), and this displays right.
But, when we declare $z to be integer, it suddenly becomes 1644.

We searched the net to check if there is some documentation on this bug, but we did not find a single thing.
Anybody got a clue ?

    I haven't yet really looked into your problem, but I must say, your avatar RULES.

    NOONE CAN ESCAPE THE QUAD-LASER!

      Okay, I think I have a decent guess at an explanation....

      It might have to do with the floating point precision. Not sure why, but the computer might be thinking the result from the subtraction of the two (double) values is 1644.999999999999999 or something.

      When the integer conversion is performed, it just chops off the decimal places. (error occurs with settype(), intval(), and casting with (int) )

      Instead, try using the bcmath functions.
      in this case, bcsub() will yield the proper answer, due to a slightly different handling of precision(s).

      Edit:
      Try adding functions that control the precision of the inital values too.
      for example, using round() (or ceil(), floor()) on the initial values (or maybe the result), will "sharpen" the precision pre-conversion.

      For reference:
      http://www.php.net/manual/en/ref.bc.php
      http://www.php.net/manual/en/language.types.float.php
      (part about float precision, conversion)

        hehe, even my boss cannot escape the wrath of my quad !

        quad $ : mv -i /b/boss/important_files /dev/bin/null
        ...whoops...

          i've checked myself... it's curious!!
          Ohh i'll have to change all my scripts... they have the number 1645 everywhere... it's indispensable for any calculation.

            yeah, or maybe...


            frylock $ cat mooninites | grep 'location' && /usr/local/athf/bin/electrozap

            🙂

              Originally posted by goldbug
              Okay, I think I have a decent guess at an explanation....

              It might have to do with the floating point precision. Not sure why, but the computer might be thinking the result from the subtraction of the two (double) values is 1644.999999999999999 or something.

              But there are only 2 decimals, and the substraction of the formula results in a round number, so how could this be ?

              When the integer conversion is performed, it just chops off the decimal places. (error occurs with settype(), intval(), and casting with (int) )

              Instead, try using the bcmath functions.
              in this case, bcsub() will yield the proper answer, due to a slightly different handling of precision(s).

              Edit:
              Try adding functions that control the precision of the inital values too.
              for example, using round() (or ceil(), floor()) on the initial values (or maybe the result), will "sharpen" the precision pre-conversion.

              For reference:
              http://www.php.net/manual/en/ref.bc.php
              http://www.php.net/manual/en/language.types.float.php
              (part about float precision, conversion)

              The 'bug' was first discovered in a Clipper app, and PHP makes the same 'mistake'. We added and tried several combinations of math-functions such as round() inside the Clipper-app, and even forcing Clipper to be precise with a command at the start of the program (Precise on, if I am correct) does not help.

              It is a big mystery why two different program-languages make the same mistake when casting the number '1645' to be integer.

                But there are only 2 decimals, and the substraction of the formula results in a round number, so how could this be ?

                I dont have a CS degree (yet), but from what I see, the internal representation of a floating point number need not be the same as that number when output.

                The solution is simple: use integers when dealing with money.

                  Originally posted by laserlight
                  I dont have a CS degree (yet), but from what I see, the internal representation of a floating point number need not be the same as that number when output.

                  The solution is simple: use integers when dealing with money.

                  Agreed.
                  One could even just use only one kind of numerical type for a certain value representation.

                    Maybe Foreigner has a song about 1645? 😉

                      That is seriously one of THE best episodes, if not #1.

                        😃 Thank you all for your suggestions, I guess we'll never know what is causing the error

                        Solution : Stricter coding when dealing with money

                          Write a Reply...