戻る

実数計算における誤差

10を3で割ると、PHPでは「10 ÷ 3 = 3.3333333333333」、JavaScriptでは「10 ÷ 3 = 3.3333333333333335」となり、言語が異なれば得られる解に違いが出ます。

10 ÷ 3で得られた解に3を掛けると、PHPでは「3.3333333333333 * 3 = 9.9999999999999」、JavaScriptでは「3.3333333333333335 * 3 = 10」一致しません。

また、1つの計算式で行うと、PHPでは「(10 ÷ 3) × 3 = 10」、JavaScriptでは「(10 ÷ 3) × 3 = 10」となり一致します。

コンピュータ言語はデータを扱える容量に違いがあり、どこかで数値を区切らなければなりません。

次の例では0.1を1000回足すと、解は「100」になりますが、コンピュータでは正しい解が得られません。

JavaScript (解:99.9999999999986)

<meta http-equiv="Content-Type" content="text/html">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<script type="text/javascript">
var answer = 0;
 
for(var i = 1; i <= 1000; i++){
	answer += 0.1;
}

window.document.write(answer);

</script>

PHP (解:99.999999999999)

<?php
header("Content-type: text/plain; charset=utf-8");

$answer = 0;

for($i = 1; $i <= 1000; $i++){
	$answer += 0.1;
}

echo $answer;
?>

これは、コンピュータが内部で2進数で計算しており、0.1を2進数に変換すると、「0.0001100110011………」となり永遠に続く数値であるため、誤差を含んだ計算になってしまいます。

これは、たとえば、計算するときに0.1に10を掛け、採取的な解を10で割るなどの工夫をすることで、誤差を解消することができます。

JavaScript (解:100)

<meta http-equiv="Content-Type" content="text/html">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<script type="text/javascript">

var answer = 0;

for(var i = 1; i <= 1000; i++){
	answer += (0.1 * 10);
}

answer /= 10;

window.document.write(answer);

</script>

PHP (解:100)

<?php
header("Content-type: text/plain; charset=utf-8");

$answer = 0;

for($i = 1; $i <= 1000; $i++){
	$answer += (0.1 * 10);
}

$answer /= 10;

echo $answer;
?>

inserted by FC2 system