smerny Posted October 20, 2009 Share Posted October 20, 2009 I have this code to convert fractional base 10 into base 2: while($num > 0) { echo "<tr><td>". $num." * 2 = </td><td>". $num*2 ."</td></tr>"; $num= $num*2; if($num>= 1) { $num-= 1; $bin .= "1"; } else { $bin .= "0"; } } anyway, stuff gets off, example: 0.7 * 2 = 1.4 0.4 * 2 = 0.8 0.8 * 2 = 1.6 0.6 * 2 = 1.2 0.2 * 2 = 0.4 0.4 * 2 = 0.8 0.8 * 2 = 1.6 0.6 * 2 = 1.2 0.2 * 2 = 0.4 0.4 * 2 = 0.8 0.8 * 2 = 1.6 0.6 * 2 = 1.2 0.2 * 2 = 0.4 0.4 * 2 = 0.799999999999 0.799999999999 * 2 = 1.6 0.599999999999 * 2 = 1.2 0.199999999997 * 2 = 0.399999999994 0.399999999994 * 2 = 0.799999999988 0.799999999988 * 2 = 1.59999999998 0.599999999977 * 2 = 1.19999999995 0.199999999953 * 2 = 0.399999999907 0.399999999907 * 2 = 0.799999999814 0.799999999814 * 2 = 1.59999999963 0.599999999627 * 2 = 1.19999999925 0.199999999255 * 2 = 0.39999999851 0.39999999851 * 2 = 0.79999999702 0.79999999702 * 2 = 1.59999999404 0.59999999404 * 2 = 1.19999998808 0.199999988079 * 2 = 0.399999976158 0.399999976158 * 2 = 0.799999952316 0.799999952316 * 2 = 1.59999990463 0.599999904633 * 2 = 1.19999980927 0.199999809265 * 2 = 0.39999961853 0.39999961853 * 2 = 0.799999237061 0.799999237061 * 2 = 1.59999847412 0.599998474121 * 2 = 1.19999694824 0.199996948242 * 2 = 0.399993896484 0.399993896484 * 2 = 0.799987792969 0.799987792969 * 2 = 1.59997558594 0.599975585938 * 2 = 1.19995117188 0.199951171875 * 2 = 0.39990234375 0.39990234375 * 2 = 0.7998046875 0.7998046875 * 2 = 1.599609375 0.599609375 * 2 = 1.19921875 0.19921875 * 2 = 0.3984375 0.3984375 * 2 = 0.796875 0.796875 * 2 = 1.59375 0.59375 * 2 = 1.1875 0.1875 * 2 = 0.375 0.375 * 2 = 0.75 0.75 * 2 = 1.5 0.5 * 2 = 1 obviously, 0.4 * 2 does not equal 0.799999999999 how can i fix these inaccuracies? Quote Link to comment https://forums.phpfreaks.com/topic/178294-solved-small-inaccuracies/ Share on other sites More sharing options...
MadTechie Posted October 20, 2009 Share Posted October 20, 2009 Floating point precision It is typical that simple decimal fractions like 0.1 or 0.7 cannot be converted into their internal binary counterparts without a small loss of precision. This can lead to confusing results: for example, floor((0.1+0.7)*10) will usually return 7 instead of the expected 8, since the internal representation will be something like 7.9. This is due to the fact that it is impossible to express some fractions in decimal notation with a finite number of digits. For instance, 1/3 in decimal form becomes 0.3. change $num= $num*2; to $num= "$num"*2; EDIT: cont. So never trust floating number results to the last digit, and never compare floating point numbers for equality. If higher precision is necessary, the arbitrary precision math functions and gmp functions are available. Quote Link to comment https://forums.phpfreaks.com/topic/178294-solved-small-inaccuracies/#findComment-940137 Share on other sites More sharing options...
smerny Posted October 20, 2009 Author Share Posted October 20, 2009 thanks, now i just need to decide when to wrap it up so it doesn't inf loop if it's a repeating binary decimal can you explain why putting parenthesis around it makes a difference? Quote Link to comment https://forums.phpfreaks.com/topic/178294-solved-small-inaccuracies/#findComment-940138 Share on other sites More sharing options...
MadTechie Posted October 20, 2009 Share Posted October 20, 2009 it's a quick dirty way to convert the float to a string, of course you could also you ctype or (string), the reason you convert to a string is because of the way floating points work, for example 100 / 3 = 33.333333333....etc now that calculation would never end, so PHP put it as 33.3 but then 33.3*3 = 99.9, now as a string you can have "33.3333333" if you wanted, and when you use it in a calculation it will be converted to the correct type ie echo "33.3333333"*3; // = 99.9999999 (now you only loss 0.0000001 when you multiple it by 3, instead of 0.1) I would recommend looking at BCMath Arbitrary Precision Mathematics EDIT: updated Quote Link to comment https://forums.phpfreaks.com/topic/178294-solved-small-inaccuracies/#findComment-940140 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.