2016-10-21 6 views
0

私はこの非常に奇妙な問題で頭を掻き回しています。私はPHPでいくつかの計算を行い、最終結果は数値です。これは整数ですが、計算が行われるため、PHPはこれを浮動小数点数と見なします。しかし、整数として型キャストすると、魔法のように1を減算します。 1と同様に整数全体が下になります。私は本当に迷っています。自分で試してみてください。PHP浮動小数点数とintは異なる数字を返します

<?php 
$number_of_rows = 10; 
$number_of_columns = 19; 
$active = array(); 

$tile = 160; 
$column = $tile/$number_of_columns; // 8.42105263158 
$rounded_down = floor($column); // 8 
$column = $column-$rounded_down; // 0.42105263158 
$column = $column*$number_of_columns; // 8 

var_dump($column); // 8 -> that is great 
var_dump((int)$column); // 7 -> WTF?!!! 

?> 

PHP 7.0.12 Linux 64ビットです。

+1

'echo serialize($ column);' 'int'にキャストすると、丸められません。 – AbraCadaver

+1

http://stackoverflow.com/questions/588004/is-floating-point-math-broken?rq=1 – AbraCadaver

+0

'$ column'の実際の値はおそらく '7.999999999999234'のようなもので、' 8 'として出力されますデフォルトの印刷精度のためです。しかし、それを '(int)'にキャストすると、端数は削除されます。 – Barmar

答えて

2

説明はWarning in PHP manualを参照してください。精度とfloor()例について語る

抜粋:

浮動小数点数は精度が限られています。それはシステムに依存しますが、PHPは通常、1.11e-16のオーダーの丸めによる最大相対誤差を与えるIEEE 754倍精度フォーマットを使用します。基本的でない算術演算は、より大きな誤差を与える可能性があり、もちろん、いくつかの演算が複合されたときにはエラー伝搬を考慮する必要があります。

さらに、基数10の浮動小数点数(0.1または0.7など)で正確に表現できる有理数は、基数2の浮動小数点数として正確には表現されません。仮数。したがって、それらは内部精度のわずかな損失なしに内部バイナリの対応物に変換することはできません。これは紛らわしい結果をもたらすことができる:内部表現が7.9999999999999991118ようなものであるので、例えば、フロア((0.1 + 0.7)* 10)は、通常、代わりに予想8 7が返され....

+0

外部リンクとしてだけでなく、ここに関連コンテンツを掲載してください。 – Barmar

+0

@Barmar、PHPは精度エラーをダンプしませんが、AbraCadaverのserializeコメントを見ると精度エラーです。 '$ column'の実際の値は' 7.9999999999999911'です – Devon

+0

ええ、私がコメントした後にそれを実現しました。 – Barmar

関連する問題