943,770 Members | Top Members by Rank

Ad:
  • PHP Discussion Thread
  • Unsolved
  • Views: 2781
  • PHP RSS
Mar 3rd, 2008
0

My PHP math is calculating weird!

Expand Post »
Hey, I've got some values that don't seem to be calculating correctly. I've got two numbers, subtracting one from another, and instead of the answer being an exact number, like .06, it's coming out as like .0599999999.

For some background, I'm working with monetary values, and since I'm so new to php and don't know of a better way, I'm simply converting all numbers to cents in the database by multiplying everything by 100, and if I'm spitting it out to the screen for the user, I'm multiplying it by 100. So anyway, I'm taking one number, say $2000 (which is stored in the database as 200000), and assigning it to a variable say called $net.
The other number is being obtained from the sum of numbers in a table, and I'm calling it $sum.

So here's how I'm getting the $net variable. The value in the table that it is pulling is 200000:

PHP Syntax (Toggle Plain Text)
  1. $query = mysql_query("SELECT * FROM mytable WHERE id=1") or die(mysql_error());
  2. while($row = mysql_fetch_array($query))
  3. {
  4. $net=$row['net']/100;
  5. }

So at this point, $net=2000. Here's how I get the $sum variable:

php Syntax (Toggle Plain Text)
  1. $query = "SELECT SUM(allotment) FROM anothertable";
  2. $result = mysql_query($query) or die(mysql_error());
  3. while($row = mysql_fetch_array($result))
  4. {
  5. $sum=$row['SUM(allotment)']/100;
  6. }

In this case, $sum=1999.94

So now I want to create a value called $leftover that is equal to $net minus $sum.
So I do this:

php Syntax (Toggle Plain Text)
  1. $leftover=$net-$sum;


It should end up being .06, but it's not, it's ending up as .059999999. Any clues as to why?


Now I noticed that if in my while statement I set the variables like this:

php Syntax (Toggle Plain Text)
  1. $sum=$row['SUM(allotment)'];

And

php Syntax (Toggle Plain Text)
  1. $net=$row['net'];

Then calculate the leftover amount from those like this:

php Syntax (Toggle Plain Text)
  1. $leftover=($net-sum)/100;

Then it works! Why?

FYI - I even printed out my variables as I went along to check them. Sure enough, it prints out:

$net=2000
$sum=1999.94

So 2000-1999.94 should equal 0.06 right? I just don't understand!
Last edited by nathanpacker; Mar 3rd, 2008 at 12:41 am.
Reputation Points: 10
Solved Threads: 0
Posting Whiz in Training
nathanpacker is offline Offline
234 posts
since May 2005
Mar 3rd, 2008
0

Re: My PHP math is calculating weird!

solve it like this:
PHP Syntax (Toggle Plain Text)
  1. echo round($leftover, 2);

Good luck.
Reputation Points: 55
Solved Threads: 11
Junior Poster
mostafadotnet is offline Offline
157 posts
since Jul 2006
Mar 3rd, 2008
0

Re: My PHP math is calculating weird!

you can also try to use number_format(float $value, int $decimals). the problem with this function is that returns a string so it will help you only for friendly display.
Reputation Points: 10
Solved Threads: 15
Junior Poster in Training
silviuks is offline Offline
95 posts
since Apr 2006
Mar 5th, 2008
0

Re: My PHP math is calculating weird!

... So 2000-1999.94 should equal 0.06 right? I just don't understand!
To find the best answer, you have to travel 30 years back in time. In a nut shell, you don't get exact answer all the time because binary floating point machine arithmetic cannot reproduce all real decimal numbers. Binary gets close, but cannot always be dead-nuts-on. It's been too long, but I'll bet that .06 cannot be exactly represented by a binary floating point number.

See Wikipedia's IEEE Floating Point Standard page for more info.
Reputation Points: 51
Solved Threads: 35
Posting Whiz in Training
Fest3er is offline Offline
238 posts
since Aug 2007
Mar 6th, 2008
0

Re: My PHP math is calculating weird!

Click to Expand / Collapse  Quote originally posted by Fest3er ...
To find the best answer, you have to travel 30 years back in time. In a nut shell, you don't get exact answer all the time because binary floating point machine arithmetic cannot reproduce all real decimal numbers. Binary gets close, but cannot always be dead-nuts-on. It's been too long, but I'll bet that .06 cannot be exactly represented by a binary floating point number.

See Wikipedia's IEEE Floating Point Standard page for more info.
That's an interesting answer. I guess I'm just confused. If you divide something by 100, you end up with two decimal places, period. Shouldn't be that dificult, rught? Well, I think I'm happy with the way I'm doing it now, like I mentioned at the last part of my post, where I do the division by 100 at the very end. I was just curious.

On a side note, anyone have a better way of working with monitary values other than storing them in the database all as pennies? I mean, I kind of like it, it's simple, and easy to understand, just wondering if there's a better way.
Reputation Points: 10
Solved Threads: 0
Posting Whiz in Training
nathanpacker is offline Offline
234 posts
since May 2005
Mar 6th, 2008
0

Re: My PHP math is calculating weird!

That's an interesting answer. I guess I'm just confused. If you divide something by 100, you end up with two decimal places, period. ...
But, grasshopper, you are forgetting that the computer does not operate in the decimal realm. It operates in the binary realm. What you think is 342/100, the computer sees as:
101010110/1100100
What you see as 2-1.94, the computer computes as, generally speaking,
10-1.1111 = .0000111
If you convert 1.1111 (binary) back to decimal, you will get 1.9375.

A silly extension of this (1.94 conversion) to many decimal/binimal places:
1.1111000010100011110101110000101000111101011100001 (binary) =
1.9399999999999995026200849679298698902130126953125 (decimal), and

1.11110000101000111101011100001010001111010111000011 (binary) =
1.94000000000000039079850466805510222911834716796875

You can see that one bit at 49 binimal places still has a not insignificant effect on the value of the number.

And for .06:
0.100110011001100110011 (binary) =
.599999904632568359375 (decimal), and

0.1001100110011001100111 (binary) =
.6000001430511474609375 (decimal)

Only rarely can real decimal numbers be exactly represented by real binary numbers. 'Real numbers' here means floating point numbers, as opposed to whole (integer) numbers. Why? In decimal, the number to the right of the '.' are 1/10, 1/100, 1/1000, etc. In binary, those numbers are 1/2, 1/4, 1/8, 1/16, etc. They only rarely align.

People have tried to get rich adding up these lost millicents and microcents. Well, at least they've tried in the movies.
Reputation Points: 51
Solved Threads: 35
Posting Whiz in Training
Fest3er is offline Offline
238 posts
since Aug 2007
Mar 6th, 2008
0

Re: My PHP math is calculating weird!

Click to Expand / Collapse  Quote originally posted by Fest3er ...
But, grasshopper, you are forgetting that the computer does not operate in the decimal realm. It operates in the binary realm. What you think is 342/100, the computer sees as:
101010110/1100100
What you see as 2-1.94, the computer computes as, generally speaking,
10-1.1111 = .0000111
If you convert 1.1111 (binary) back to decimal, you will get 1.9375.

A silly extension of this (1.94 conversion) to many decimal/binimal places:
1.1111000010100011110101110000101000111101011100001 (binary) =
1.9399999999999995026200849679298698902130126953125 (decimal), and

1.11110000101000111101011100001010001111010111000011 (binary) =
1.94000000000000039079850466805510222911834716796875

You can see that one bit at 49 binimal places still has a not insignificant effect on the value of the number.

And for .06:
0.100110011001100110011 (binary) =
.599999904632568359375 (decimal), and

0.1001100110011001100111 (binary) =
.6000001430511474609375 (decimal)

Only rarely can real decimal numbers be exactly represented by real binary numbers. 'Real numbers' here means floating point numbers, as opposed to whole (integer) numbers. Why? In decimal, the number to the right of the '.' are 1/10, 1/100, 1/1000, etc. In binary, those numbers are 1/2, 1/4, 1/8, 1/16, etc. They only rarely align.

People have tried to get rich adding up these lost millicents and microcents. Well, at least they've tried in the movies.
Ah, gotcha. Well then, how do calculators do it so well dang it? (you don't have to answer that. Semi-rhetorical question.)
Reputation Points: 10
Solved Threads: 0
Posting Whiz in Training
nathanpacker is offline Offline
234 posts
since May 2005

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in PHP Forum Timeline: Looking for experienced PHP programmer for online sim game.
Next Thread in PHP Forum Timeline: Form Crapped Out...





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC