Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations MikeeOK on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Modulus problem in PHP 1

Status
Not open for further replies.

ressing1

Programmer
Jul 30, 2004
4
US
Can anyone explain why this happens:

<?
$bill=(.29*100);
$ted=29;
print ($bill % 29)."<br>\n";
print ($ted % 29);
?>

Result:
28 Incorrect
0 Correct
 
I'd bet good money it's a rounding error.

(.29 * 100) is not equal to 29. The former is a floating-point number, the latter is an integer. Remember, all floating-point numbers are an approximations of values, as many decimal numbers cannot be exactly represented in floating-point format.

The modulus operator, I believe, is only defined within PHP for integers, so the value (.29 * 100) must be converted to integer.

This code:

Code:
<?
$bill=(.29*100);
print (int) $bill;
?>

Outputs 28, not the expected 29.


See the fmod()[.link] function for a floating-point modulo operator.


Want the best answers? [url=http://www.catb.org/~esr/faqs/smart-questions.html]Ask the best questions!


TANSTAAFL!!
 
I figured it was something like that, but I tried using fmod and it made no difference. Is there a way to convert a number into an integer? I tried using floor(), but that didn't work either.
 
The problem, again, is the inexactness of floating-point variables.

In the case of (.29 * 100), the floor() function returns 28. ceil() will return 29.

ceil() works because PHP's value is slightly less than 29. But only in this case -- some other value may be slightly higher than the integer value and will return a number one too great.

What are you trying to do?


Want the best answers? Ask the best questions!

TANSTAAFL!!
 
You'll Laugh at me , but here goes. I am writing a converter for wizard gold :). I solved this by using round()
$bob represents US Dollars.
1 Galleon =17 Sickles=493 Knuts.
Assumes 1 penny=1 knut.
Code:
<?
$bob=.29;
$knuts =round($bob*100);
$sickles = ($knuts/29);
$knuts = ($knuts % 29);
$galleons = ($sickles/17);
$sickles = ($sickles % 17);
print floor($galleons)." Galleons ".floor($sickles)." Sickles and ".floor($knuts)." Knuts<br>";
?>
 
It seems to me that you're writing the typical "making change" program, but with non-standard sizes of coins.

Are you trying to get the minimum number of coins required? If so, you should get the largest coin first.


Anyway, you can peform the multiplication typographically rather than arithmetically:

$bob=.29;
$bob_array = explode ('.', $bob, 2);
if (count($bob_array) != 1)
{
$bob = ltrim($bob_array[0],'0') . $bob_array[1];
}





Want the best answers? Ask the best questions!

TANSTAAFL!!
 
Basically. I didn't want to grab it typograchically in case someone put in an odd value such as a half penny.
$bob =.295 for example. Rounding the product works. Thanks for helping me out.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top