Jump to content

[SOLVED] small inaccuracies


smerny

Recommended Posts

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?

Link to comment
https://forums.phpfreaks.com/topic/178294-solved-small-inaccuracies/
Share on other sites

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.

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

Archived

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

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.