Jump to content

Strange Math Error in PHP


ShadowMage

Recommended Posts

Ok, before I give you code or anything of that sort, can somebody tell me what the following statement should evaluate to:ceil((112*12)/268.8)*2*1The answer I get is not the answer that PHP gives me. What do you guys get for the answer?

Link to comment
Share on other sites

PHP gives you 12, I suppose (haven't tested it)*? That would just be because of floating-point inaccuracies (i.e. it can't represent 268.8 in binary exactly, so it stores the closest approximation it can, which is smaller than 268.8).http://en.wikipedia.org/wiki/Single_precision* edit: eh, no, I tested it, I get 10 (the right answer)...

Link to comment
Share on other sites

PHP gives you 12, I suppose (haven't tested it)? That would just be because of floating-point inaccuracies (i.e. it can't represent 268.8 in binary exactly, so it stores the closest approximation it can, which is smaller than 268.8).http://en.wikipedia.org/wiki/Single_precision
Precisely! Hmm...so is there a decent way to work around this issue?EDIT: I just noticed your edit. Perhaps it's because that's a simplified representation. Here's the exact formula:ceil((112*12)/((112/ceil(112/24))*12))
Link to comment
Share on other sites

Use integers as much as possible.Edit: Yes, I get 12 for that expression multiplied by two. As you can see, keeping it simple also helps, as there is less room for error.

Link to comment
Share on other sites

Use integers as much as possible. I don't know to what extent PHP stores intermediate results of expressions symbolically, but you could try, for example:
ceil((112*12)/(2688/10))*2

Thing is this is somewhat of a complicated script. The immediate code around the formula is here:
$PieceLength = ($length/ceil($length/$tmpExtrLength))*12;$arrPieces[$numTypes]['Frame'][$index]["PcLength"] = nearestFraction($PieceLength, 1/16);$numPieces = ceil(($length*12)/$PieceLength)*2*$qty;$arrPieces[$numTypes]['Frame'][$index]["Pieces"] = $numPieces;

$length and $tmpExtrLength are values pulled from a database. $tmpExtrLength will probably never be a decimal value but $length quite often will be. If I break these formulas apart, might it solve my problem? For example:

$barsPerLength = $length/$tmpExtrLength;$PieceLength = ($length/ceil($barsPerLength))*12;$arrPieces[$numTypes]['Frame'][$index]["PcLength"] = nearestFraction($PieceLength, 1/16);

Link to comment
Share on other sites

Ok, before I give you code or anything of that sort, can somebody tell me what the following statement should evaluate to:ceil((112*12)/268.8)*2*1The answer I get is not the answer that PHP gives me. What do you guys get for the answer?
The answer PHP and I get is 10.Here is the math:ceil( (112*12)/268.8) *2*1112 x 12 = 13441344 ÷ 268.8 = 5ceil(5) = 55 x 2 x 1 = 10Where is the problem?Roddy
Link to comment
Share on other sites

The answer PHP and I get is 10.Here is the math:ceil( (112*12)/268.8) *2*1112 x 12 = 13441344 ÷ 268.8 = 5ceil(5) = 55 x 2 x 1 = 10Where is the problem?Roddy
We covered that. :)
EDIT: I just noticed your edit. Perhaps it's because that's a simplified representation. Here's the exact formula:ceil((112*12)/((112/ceil(112/24))*12))
It comes down to how far it's been simplified before it gets put into the ceil() function. I'm in the process of breaking my formulas apart to try to simplify them before I pass them to ceil(). I'll post back to let you know how it works out.
Link to comment
Share on other sites

It comes down to how far it's been simplified before it gets put into the ceil() function. I'm in the process of breaking my formulas apart to try to simplify them before I pass them to ceil(). I'll post back to let you know how it works out.
Turns out it doesn't matter if I break them up or not. I still get the same results. I solved my issue by converting the $PieceLength to the nearest fraction right away:
$PieceLength = nearestFraction(($length/ceil($length/$tmpExtrLength))*12, 1/16); //Convert here, that way $PieceLength = 268.8125$arrPieces[$numTypes]['Frame'][$index]["PcLength"] = $PieceLength; //Instead of converting it here$numPieces = ceil(($length*12)/$PieceLength)*2*$qty;$arrPieces[$numTypes]['Frame'][$index]["Pieces"] = $numPieces;

These fractions should be much easier to represent in binary.Thanks for all your help guys!

Link to comment
Share on other sites

We covered that. :)It comes down to how far it's been simplified before it gets put into the ceil() function. I'm in the process of breaking my formulas apart to try to simplify them before I pass them to ceil(). I'll post back to let you know how it works out.
You might like to compare the results of the following two formuations:
echo ceil((112*12)/(112/ceil(112/24))*12);echo ceil((112*12)/(112/ceil(112/24)*12));

The key partial expressions are give below:

(112/ceil(112/24))*12112/ceil(112/24)*12

Roddy

Link to comment
Share on other sites

You might like to compare the results of the following two formuations:
echo ceil((112*12)/(112/ceil(112/24))*12);echo ceil((112*12)/(112/ceil(112/24)*12));

The first one gives me 721, which is way off. The parens are not in the order that they need to be for the calculation.The second gives me 6, which is the same answer I got from my formula. The parens in this one match what I have pretty closely (it's missing one set, but that set is unimportant concerning order of operations).My formula:ceil((112*12)/((112/ceil(112/24))*12))should return 5, but instead returns 6. Synook pointed out the reason for this in his first reply, which is that certain numbers cannot be represented exactly in binary and so the closest approximation is used, which in this case produces unexpected results.
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...