Someone please explain what alternate universe I fell into this
afternoon when PHP started telling me that 2 doesn't equal 2.
Not sure about you, but when I run this, it tells me 59001.31 doesn't
equal 59001.31. Change each side of the equation by a hundreth or two
and it checks. Change it a bit more, and it won't.
_What_ is going on here?!
<?php
$subtotal=59001.31;
$principal=58605.33;
$interest=395.98;
$check=$principal+$interest;
echo("<pre>");
echo("Check: " . $check . "\n");
echo("Subtotal: " . $subtotal . "\n");
if($check!=$subtotal) {
echo("Check (" . $check . ") does not equal subtotal (" .
$subtotal . ")"); // Check doesn't equal subtotal
}
else {
echo("Check (" . $check . ") equals subtotal (" . $subtotal .
")"); // Check does equal subtotal
}
echo("</pre>");
?>
--
Craig Bailey, Communications Coordinator
Vermont Housing Finance Agency (VHFA)
164 St. Paul St., P.O. Box 408
Burlington, Vt. 05402-0408
Email: cb*****@vhfa.org | Web: www.vhfa.org
Phone: (802) 652-3463 | Fax: (802) 864-5746 17 4012
Floating operations always introduces small errors, that's why. Run this and
you'll see:
<?php
$subtotal=59001.31;
$principal=58605.33;
$interest=395.98;
$check=$principal+$interest;
$diff=$check - $subtotal;
echo("<pre>");
echo("Check: " . $check . "\n");
echo("Subtotal: " . $subtotal . "\n");
if($check!=$subtotal) {
echo("Check (" . $check . ") does not equal subtotal (" .
$subtotal . ")."); // Check doesn't equal subtotal
printf("Their difference is %01.40f", $diff);
}
else {
echo("Check (" . $check . ") equals subtotal (" . $subtotal .
")"); // Check does equal subtotal
}
echo("</pre>");
?>
The decimal part of a float is represented internally as a fraction of some
denominator that is of the power of 2. Decimals that are not
1/(2^n)therefore cannot be represented precisely.
59001.31 is 59001 + 5325759447 / 2^34 or
59001.3099999999976716935634613037109375
58605.33 is 58605 + 22677427323 / 2^36 or
58605.330000000001746229827404022216796875
395.98 is 395 + 2155042790441 / 2^41 or
395.9800000000000181898940354585647583007813
When you add up the fractions, lo and behold, they don't add up exactly (the
error is 1/(2^37)).
You should do what Mike suggested. Whenever you divide something or multiple
something by a floating point number, pass the result through round().
Uzytkownik "Craig Bailey" <cb*****@vhfa.org> napisal w wiadomosci
news:cb***************************@sover.net.clien t.newsread.com... Someone please explain what alternate universe I fell into this afternoon when PHP started telling me that 2 doesn't equal 2.
Not sure about you, but when I run this, it tells me 59001.31 doesn't equal 59001.31. Change each side of the equation by a hundreth or two and it checks. Change it a bit more, and it won't.
_What_ is going on here?!
<?php $subtotal=59001.31; $principal=58605.33; $interest=395.98; $check=$principal+$interest; echo("<pre>"); echo("Check: " . $check . "\n"); echo("Subtotal: " . $subtotal . "\n"); if($check!=$subtotal) { echo("Check (" . $check . ") does not equal subtotal (" . $subtotal . ")"); // Check doesn't equal subtotal } else { echo("Check (" . $check . ") equals subtotal (" . $subtotal . ")"); // Check does equal subtotal } echo("</pre>"); ?>
-- Craig Bailey, Communications Coordinator Vermont Housing Finance Agency (VHFA) 164 St. Paul St., P.O. Box 408 Burlington, Vt. 05402-0408 Email: cb*****@vhfa.org | Web: www.vhfa.org Phone: (802) 652-3463 | Fax: (802) 864-5746
"Chung Leong" <ch***********@hotmail.com> wrote You should do what Mike suggested. Whenever you divide something or
multiple something by a floating point number, pass the result through round().
LOL somebody here capable of programming? Just ironic, reading too much
bulls*** here.
What should somebody use floats for, when always rounding that shit before
doing mathematics?
If you have to use floats and need to to compare them, round them before
comparing. But when using floats that have to be compared, your concept is
broken.
Carl
In article <2O*****************@newssvr27.news.prodigy.com> ,
"CountScubula" <me@scantek.hotmail.com> wrote: I did not get into it, but just for a quick reference, when you deal with money in software/scripts, it is best to convert over to cents, thus 395.98 is 39598, deal with all numbers as whole numbers, and when you go to print it then add the decimal, the decimal is a human thing, for parts of a dollar.
Thanks for all the help. Though I admit that I'm a little floored that a
scripting language doesn't have a more elegant way to handle something
like ... er ... _numbers_.
And here I thought computers were _good_ with numbers ...
--
Craig Bailey, Communications Coordinator
Vermont Housing Finance Agency (VHFA)
164 St. Paul St., P.O. Box 408
Burlington, Vt. 05402-0408
Email: cb*****@vhfa.org | Web: www.vhfa.org
Phone: (802) 652-3463 | Fax: (802) 864-5746
On Tue, 13 Jan 2004 18:20:34 GMT, Craig Bailey <cb*****@vhfa.org> wrote: In article <2O*****************@newssvr27.news.prodigy.com> , "CountScubula" <me@scantek.hotmail.com> wrote:
I did not get into it, but just for a quick reference, when you deal with money in software/scripts, it is best to convert over to cents, thus 395.98 is 39598, deal with all numbers as whole numbers, and when you go to print it then add the decimal, the decimal is a human thing, for parts of a dollar.
Thanks for all the help. Though I admit that I'm a little floored that a scripting language doesn't have a more elegant way to handle something like ... er ... _numbers_.
And here I thought computers were _good_ with numbers ...
They are. But there have to be compromises when storing floating point
numbers. For example, if you do 1.0/3.0, you get 0.33333 recurring. How do you
store an infinite number of decimal places in a (small) finite space?
There are floating point storage schemes that can represent recurring numbers
exactly, but they're relatively complicated. The IEEE format used by most
processors lets you store the number in a smallish space and have simpler
circuitry to process it, but the compromise is you lose accuracy after a
certain number of significant digits.
It's a hardware thing, not a language thing.
So, if you want exact maths on a computer, use integers, or find one of the
exact floating point maths libraries and put up with the performance penalties.
--
Andy Hassall <an**@andyh.co.uk> / Space: disk usage analysis tool
<http://www.andyh.co.uk> / <http://www.andyhsoftware.co.uk/space>
CountScubula wrote: I did not get into it, but just for a quick reference, when you deal with money in software/scripts, it is best to convert over to cents, thus 395.98 is 39598, deal with all numbers as whole numbers, and when you go to print it then add the decimal, the decimal is a human thing, for parts of a dollar.
just my 2 cents or ($.02)
-- Mike Bradley
"Craig Bailey" <cb*****@vhfa.org> wrote in message news:cb***************************@sover.net.clien t.newsread.com... Someone please explain what alternate universe I fell into this afternoon when PHP started telling me that 2 doesn't equal 2.
Not sure about you, but when I run this, it tells me 59001.31 doesn't equal 59001.31. Change each side of the equation by a hundreth or two and it checks. Change it a bit more, and it won't.
_What_ is going on here?!
Heheh - I remember them telling us that in my 1st year of computer science
:) I so rarely deal with currency stuff I'd almost forgotten! Thanks for
the reminder.
James
--
Fortune cookie says:
America has been discovered before, but it has always been hushed up.
- Oscar Wilde
"CountScubula" <me@scantek.hotmail.com> schrieb im Newsbeitrag
news:2O*****************@newssvr27.news.prodigy.co m... I did not get into it, but just for a quick reference, when you deal with money in software/scripts, it is best to convert over to cents, thus
395.98 is 39598, deal with all numbers as whole numbers, and when you go to print it then add the decimal, the decimal is a human thing, for parts of a dollar.
So when using signed 32 bit integer values (the only PHP knows) you have
2,000,000,000 Cent or better 20,000,000.00 $ to be the limit of economics.
PHP then starts converting values to FLOAT. So when handling huge values one
better doesn't compare without additional rounding.
Carl
In article <i4********************************@4ax.com>,
Andy Hassall <an**@andyh.co.uk> wrote: But there have to be compromises when storing floating point numbers. For example, if you do 1.0/3.0, you get 0.33333 recurring. How do you store an infinite number of decimal places in a (small) finite space?
But that's not what I'm doing. I'm doing addition. I'm taking 10.25 and
adding it to 11.4.
Why can't the computer recognize that as 21.65?
If $total=21.65 and I compare that to 10.25+11.4, the fact that the
computer might not be able to recognize a match perplexs me.
I set $total=21.65 and ask it to print $total. It prints 21.65.
I set $anotherTotal=10.25+11.4. I ask it to print $anotherTotal. It
prints 21.65.
_Then_ I ask it if $total equals $anotherTotal and is says "No."
Huh?
--
Floydian Slip(tm) - "Broadcasting from the dark side of the moon"
Random Precision Productions(tm)
67 Union St. #2D, Winooski, Vt. 05404-1948 USA
Sundays, 7-8 pm - Champ 101.3 FM, Colchester; 102.1 FM, Randolph, Vt. cc*@floydianslip.com - AIM: RandomPrec - www.floydianslip.com
Mike's suggestion was to use fixed point math. Read the post, pal.
Uzytkownik "Carl Melot" <ca*****@linkwave.org> napisal w wiadomosci
news:bu*************@news.t-online.com... What should somebody use floats for, when always rounding that shit before doing mathematics?
If you have to use floats and need to to compare them, round them before comparing. But when using floats that have to be compared, your concept is broken.
Carl
On Wed, 14 Jan 2004 00:31:57 GMT, Craig Bailey <cc*@floydianslip.com> wrote: In article <i4********************************@4ax.com>, Andy Hassall <an**@andyh.co.uk> wrote:
But there have to be compromises when storing floating point numbers. For example, if you do 1.0/3.0, you get 0.33333 recurring. How do you store an infinite number of decimal places in a (small) finite space?
But that's not what I'm doing. I'm doing addition. I'm taking 10.25 and adding it to 11.4.
Why can't the computer recognize that as 21.65?
If $total=21.65 and I compare that to 10.25+11.4, the fact that the computer might not be able to recognize a match perplexs me.
I set $total=21.65 and ask it to print $total. It prints 21.65.
I set $anotherTotal=10.25+11.4. I ask it to print $anotherTotal. It prints 21.65.
_Then_ I ask it if $total equals $anotherTotal and is says "No."
For really gory details into Why, search for 'IEEE floating point
representation'. For example: http://www.math.grin.edu/~stone/cour...EEE-reals.html
Since the system is based on binary powers, the inaccuracies don't come in
places that you might think if you're thinking in decimal. Various floating
point numbers that have an exact decimal representation end up as recurring
binary representation in the IEEE scheme, so get approximated. Taking the
numbers you pointed out:
<pre>
<?php
$x = 10.25;
$y = 11.4;
printf("x = %10.32f\n", $x);
printf("y = %10.32f\n", $y);
printf("x + y = %10.32f\n", $x+$y);
?>
</pre>
Outputs:
x = 10.25000000000000000000000000000000
y = 11.40000000000000035527136788005009
x + y = 21.64999999999999857891452847979963
I really can't remember the exact details of the IEEE representation any more,
I think like most people I just accept there are inaccuracies and so you
arrange code to expect them, and to minimise the number of repeated operations
(the more you do, the more inaccurate you get).
But from the above, you can see that 10.25 can be exactly represented, but
whilst it's got pretty close to 11.4, it's very slightly off. And again with
the sum of the two, it's slightly off.
With the IEEE representation, there is a (very small) value 'epsilon' which is
a limit of the inaccuracy between the number you want and the stored
representation of it. Check Google, and computer architecture books for the
boring but useful explanation of how it works.
--
Andy Hassall <an**@andyh.co.uk> / Space: disk usage analysis tool
<http://www.andyh.co.uk> / <http://www.andyhsoftware.co.uk/space>
Craig Bailey wrote: I set $total=21.65 and ask it to print $total. It prints 21.65.
I set $anotherTotal=10.25+11.4. I ask it to print $anotherTotal. It prints 21.65.
_Then_ I ask it if $total equals $anotherTotal and is says "No."
Huh?
The _internal_ representation of floating-point numbers is not precise!
Try this:
<?php
printf(" %2.8f\n %2.8f\n %2.8f\n\n", 10.25, 11.4, 21.65);
printf("%2.22f\n%2.22f\n%2.22f\n", 10.25, 11.4, 21.65);
?>
--
--= my mail box only accepts =--
--= Content-Type: text/plain =--
--= Size below 10001 bytes =--
On Tue, 13 Jan 2004 18:20:34 +0000, Craig Bailey wrote: Thanks for all the help. Though I admit that I'm a little floored that a scripting language doesn't have a more elegant way to handle something like ... er ... _numbers_.
And here I thought computers were _good_ with numbers ...
This only shows how ignorant you are about computers.
Ed
In article <pa****************************@shaw.ca>,
Ed Seedhouse <es********@shaw.ca> wrote: On Tue, 13 Jan 2004 18:20:34 +0000, Craig Bailey wrote:
Thanks for all the help. Though I admit that I'm a little floored that a scripting language doesn't have a more elegant way to handle something like ... er ... _numbers_.
And here I thought computers were _good_ with numbers ...
This only shows how ignorant you are about computers.
Ed
Me ignorant. You arrogant. All comes out in the wash, I guess.
--
Floydian Slip(tm) - "Broadcasting from the dark side of the moon"
Random Precision Productions(tm)
67 Union St. #2D, Winooski, Vt. 05404-1948 USA
Sundays, 7-8 pm - Champ 101.3 FM, Colchester; 102.1 FM, Randolph, Vt. cc*@floydianslip.com - AIM: RandomPrec - www.floydianslip.com
Craig Bailey wrote: In article <pa****************************@shaw.ca>, Ed Seedhouse <es********@shaw.ca> wrote:
On Tue, 13 Jan 2004 18:20:34 +0000, Craig Bailey wrote:
Thanks for all the help. Though I admit that I'm a little floored that a scripting language doesn't have a more elegant way to handle something like ... er ... _numbers_.
And here I thought computers were _good_ with numbers ...
This only shows how ignorant you are about computers.
Ed
Me ignorant. You arrogant. All comes out in the wash, I guess.
If you're programming you really should understand this problem. It's very
basic. That's not a dig or anything, just a suggestion on how to further your
skills. The following page explains it pretty well, I think. (sorry if link
doesn't make it under 80 character cut-off.) http://oopweb.com/Assembly/Documents...14/CH14-1.html
Regards,
Shawn
--
Shawn Wilson sh***@glassgiant.com http://www.glassgiant.com
I have a spam filter. Please include "PHP" in the
subject line to ensure I'll get your message.
Craig Bailey wrote: In article <pa****************************@shaw.ca>, Ed Seedhouse <es********@shaw.ca> wrote:
On Tue, 13 Jan 2004 18:20:34 +0000, Craig Bailey wrote:
Thanks for all the help. Though I admit that I'm a little floored that a scripting language doesn't have a more elegant way to handle something like ... er ... _numbers_.
And here I thought computers were _good_ with numbers ...
This only shows how ignorant you are about computers.
Ed
Me ignorant. You arrogant. All comes out in the wash, I guess.
Or read the "Floating point precision" box in the following: http://ca.php.net/manual/en/language....float.casting
Regards,
Shawn
--
Shawn Wilson sh***@glassgiant.com http://www.glassgiant.com
I have a spam filter. Please include "PHP" in the
subject line to ensure I'll get your message.
On Wed, 14 Jan 2004 10:12:54 -0400, Shawn Wilson
<sh***@glassgiant.com> brought forth from the murky depths: http://oopweb.com/Assembly/Documents...14/CH14-1.html
All chars came through, 404 error anyway, Shawn, both in NN7 and IE6.
Not Found
The requested URL /Assembly/VolumeFrames.html was not found on this
server.
Additionally, a 404 Not Found error was encountered while trying to
use an ErrorDocument to handle the request.
--------------------------------------------------------------------------------
Apache/1.3.29 Server at www.oopweb.com Port 80
----------------------------------
VIRTUE...is its own punishment http://www.diversify.com Website Applications
==================================================
Larry Jaques wrote: On Wed, 14 Jan 2004 10:12:54 -0400, Shawn Wilson <sh***@glassgiant.com> brought forth from the murky depths:
http://oopweb.com/Assembly/Documents...14/CH14-1.html
All chars came through, 404 error anyway, Shawn, both in NN7 and IE6.
Not Found The requested URL /Assembly/VolumeFrames.html was not found on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
Weird. It works fine in NS 4.75 (just checked it again, not from cache).
Anyway, the php.net link should work...
Regards,
Shawn
--
Shawn Wilson sh***@glassgiant.com http://www.glassgiant.com
I have a spam filter. Please include "PHP" in the
subject line to ensure I'll get your message.
On Wed, 14 Jan 2004 11:08:13 -0400, Shawn Wilson
<sh***@glassgiant.com> brought forth from the murky depths: Larry Jaques wrote: On Wed, 14 Jan 2004 10:12:54 -0400, Shawn Wilson <sh***@glassgiant.com> brought forth from the murky depths:
>http://oopweb.com/Assembly/Documents...14/CH14-1.html
All chars came through, 404 error anyway, Shawn, both in NN7 and IE6.
Not Found The requested URL /Assembly/VolumeFrames.html was not found on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
Weird. It works fine in NS 4.75 (just checked it again, not from cache). Anyway, the php.net link should work...
I'll review both, thanks.
I hit the root domain, followed the links, and it worked. Evidently
it needed the stupid HTML frames to be set up from another page. But
what do programmers know about web design? <g>
----------------------------------
VIRTUE...is its own punishment http://www.diversify.com Website Applications
================================================== This discussion thread is closed Replies have been disabled for this discussion. Similar topics
reply
views
Thread by Jussi Mononen |
last post: by
|
3 posts
views
Thread by Tony |
last post: by
|
17 posts
views
Thread by cwdjrxyz |
last post: by
|
8 posts
views
Thread by Eps |
last post: by
|
11 posts
views
Thread by Sambo |
last post: by
|
5 posts
views
Thread by Paolo |
last post: by
|
reply
views
Thread by kirby.urner |
last post: by
|
10 posts
views
Thread by Joseph Geretz |
last post: by
| | | | | | | | | | | |