473,323 Members | 1,560 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,323 software developers and data experts.

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: cb*****@vhfa.org | Web: www.vhfa.org
Phone: (802) 652-3463 | Fax: (802) 864-5746
Jul 17 '05 #1
17 4149
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

Jul 17 '05 #2

"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
Jul 17 '05 #3
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
Jul 17 '05 #4
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>
Jul 17 '05 #5
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

Jul 17 '05 #6
"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
Jul 17 '05 #7
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
Jul 17 '05 #8
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

Jul 17 '05 #9
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>
Jul 17 '05 #10
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 =--
Jul 17 '05 #11
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
Jul 17 '05 #12
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
Jul 17 '05 #13
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.
Jul 17 '05 #14
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.
Jul 17 '05 #15
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
==================================================
Jul 17 '05 #16
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.
Jul 17 '05 #17
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
==================================================
Jul 17 '05 #18

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Jussi Mononen | last post by:
Hi, I'm having problems to successfully execute the test scripts on a Compaq host ( OSF1 tr51bdev V5.1 2650 alpha ). Almost all tests end up with the following error message "PARI: *** ...
3
by: Tony | last post by:
On PageA I have: <Input Type="CheckBox" Name="chkBox" Size="1" Value="True" checked> Which works fine! On PageB I have; <%If Request("chkBox")=True Then Response.Write "True" Else
17
by: cwdjrxyz | last post by:
Javascript has a very small math function list. However there is no reason that this list can not be extended greatly. Speed is not an issue, unless you nest complicated calculations several levels...
8
by: Eps | last post by:
I have a for loop and i want to do different things depending on whether the counter is even or odd. I know there is probably some really simple math thing that can do this but my maths is a bit...
11
by: Sambo | last post by:
I have the following module: ------------------------------- import math def ac_add_a_ph( amp1, ph1, amp2, ph2 ): amp3 = 0.0 ph3 = 0.0 ac1 = ( 0, 0j ) ac2 = ( 0, 0j )
5
by: Paolo | last post by:
Hi all! I have to create an application that receive some packet from an interface and builds a file from those. In the header there are three fields: one is the total lenght of the file, one is...
0
by: kirby.urner | last post by:
Cyber-curricula have a leveling aspect, as kids nearer Katrina's epicenter tune in and bliss out on 'Warriors of the Net' (why wait for stupid big dummy textbooks to catch up?). They feel more...
10
by: Joseph Geretz | last post by:
I need to calculate miles per degree longitude, which obviously depends on latitude since lines of longitude converge at the poles. Via Google, I've come up with the following calculation: ...
4
by: davidson1 | last post by:
Hai Friends, I have a javascript program , as a snow a single picture will fall from above to below in the browser.It is worked properly when my friend was using.Sudennly it is...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.