Check my math! - PHP Development

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 . ")"); // ...

1. Check my math!

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: [email]cbaileyvhfa.org[/email] | Web: [url]www.vhfa.org[/url]
Phone: (802) 652-3463 | Fax: (802) 864-5746
Craig Bailey Guest

2. Re: Check my math!

"Craig Bailey" <cbaileyvhfa.org> wrote:
> Someone please explain what alternate universe I fell into this
> afternoon when PHP started telling me that 2 doesn't equal 2.
[url]http://de2.php.net/manual/en/language.types.float.php[/url]

Regards
Carl

Carl Melot Guest

3. Re: Check my math!

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)

--
[url]http://www.gzentools.com[/url] -- free online php tools
"Craig Bailey" <cbaileyvhfa.org> wrote in message
> 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: [email]cbaileyvhfa.org[/email] | Web: [url]www.vhfa.org[/url]
> Phone: (802) 652-3463 | Fax: (802) 864-5746

CountScubula Guest

4. Re: Check my math!

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" <cbaileyvhfa.org> napisal w wiadomosci
> 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: [email]cbaileyvhfa.org[/email] | Web: [url]www.vhfa.org[/url]
> Phone: (802) 652-3463 | Fax: (802) 864-5746

Chung Leong Guest

5. Re: Check my math!

"Chung Leong" <chernyshevskyhotmail.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 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

Carl Melot Guest

6. Re: Check my math!

In article <2ODMb.8937\$XZ6.4088newssvr27.news.prodigy.com> ,
"CountScubula" <mescantek.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: [email]cbaileyvhfa.org[/email] | Web: [url]www.vhfa.org[/url]
Phone: (802) 652-3463 | Fax: (802) 864-5746
Craig Bailey Guest

7. Re: Check my math!

On Tue, 13 Jan 2004 18:20:34 GMT, Craig Bailey <cbaileyvhfa.org> wrote:
>In article <2ODMb.8937\$XZ6.4088newssvr27.news.prodigy.com> ,
> "CountScubula" <mescantek.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 <andyandyh.co.uk> / Space: disk usage ysis tool
<http://www.andyh.co.uk> / <http://www.andyhsoftware.co.uk/space>
Andy Hassall Guest

8. Re: Check my math!

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)
>
> --
> "Craig Bailey" <cbaileyvhfa.org> wrote in message
>> 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
--
America has been discovered before, but it has always been hushed up.
- Oscar Wilde

Centurion Guest

9. Re: Check my math!

"CountScubula" <mescantek.hotmail.com> schrieb im Newsbeitrag
news:2ODMb.8937\$XZ6.4088newssvr27.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

Carl Melot Guest

10. Re: Check my math!

In article <i4i8005okpeop8as8lqatm6ld1354qr2984ax.com>,
Andy Hassall <andyandyh.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

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.
[email]ccbfloydianslip.com[/email] - AIM: RandomPrec - [url]www.floydianslip.com[/url]
Craig Bailey Guest

11. Re: Check my math!

Mike's suggestion was to use fixed point math. Read the post, pal.

news:bu06r5\$cps\$07\$1news.t-online.com...
> What should somebody use floats for, when always rounding that 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
>
>

Chung Leong Guest

12. Re: Check my math!

On Wed, 14 Jan 2004 00:31:57 GMT, Craig Bailey <ccbfloydianslip.com> wrote:
>In article <i4i8005okpeop8as8lqatm6ld1354qr2984ax.com>,
> Andy Hassall <andyandyh.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
>
>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:

[url]http://www.math.grin.edu/~stone/courses/fundamentals/IEEE-reals.html[/url]

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 <andyandyh.co.uk> / Space: disk usage ysis tool
<http://www.andyh.co.uk> / <http://www.andyhsoftware.co.uk/space>
Andy Hassall Guest

13. Re: Check my math!

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 =--
Pedro Graca Guest

14. Re: Check my math!

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
Ed Seedhouse Guest

15. Re: Check my math!

In article <pan.2004.01.14.02.00.44.621055shaw.ca>,
Ed Seedhouse <eseedhouseshaw.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.
[email]ccbfloydianslip.com[/email] - AIM: RandomPrec - [url]www.floydianslip.com[/url]
Craig Bailey Guest

16. Re: Check my math!

Craig Bailey wrote:
>
> In article <pan.2004.01.14.02.00.44.621055shaw.ca>,
> Ed Seedhouse <eseedhouseshaw.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.)

[url]http://oopweb.com/Assembly/Doents/ArtOfAssembly/Volume/Chapter_14/CH14-1.html[/url]

Regards,
Shawn
--
Shawn Wilson
[email]shawnglassgiant.com[/email]
[url]http://www.glassgiant.com[/url]

I have a spam filter. Please include "PHP" in the
subject line to ensure I'll get your message.
Shawn Wilson Guest

17. Re: Check my math!

Craig Bailey wrote:
>
> In article <pan.2004.01.14.02.00.44.621055shaw.ca>,
> Ed Seedhouse <eseedhouseshaw.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:

[url]http://ca.php.net/manual/en/language.types.float.php#language.types.float.cast ing[/url]

Regards,
Shawn
--
Shawn Wilson
[email]shawnglassgiant.com[/email]
[url]http://www.glassgiant.com[/url]

I have a spam filter. Please include "PHP" in the
subject line to ensure I'll get your message.
Shawn Wilson Guest

18. Re: Check my math!

On Wed, 14 Jan 2004 10:12:54 -0400, Shawn Wilson
<com> brought forth from the murky depths:

All chars came through, 404 error anyway, Shawn, both in NN7 and IE6.

server.

use an ErrorDoent 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 Guest

19. Re: Check my math!

Larry Jaques wrote:
>
> All chars came through, 404 error anyway, Shawn, both in NN7 and IE6.
>
> server.
>
> use an ErrorDoent to handle the request.[/ref]

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
com
http://www.glassgiant.com

I have a spam filter. Please include "PHP" in the
subject line to ensure I'll get your message.
Shawn Guest

20. Re: Check my math!

On Wed, 14 Jan 2004 11:08:13 -0400, Shawn Wilson
<com> brought forth from the murky depths:

>>
>> All chars came through, 404 error anyway, Shawn, both in NN7 and IE6.
>>
>> server.
>>
>> use an ErrorDoent to handle the request.[/ref]
>
>Weird. It works fine in NS 4.75 (just checked it again, not from cache).
>Anyway, the php.net link should work...[/ref]

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
==================================================
Larry Guest

Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•