[PHP-users 11918] Re: sprintfについて
Osamu Shigematsu
php-users@php.gr.jp
Mon, 02 Dec 2002 14:21:42 +0900
重松です。こんにちは。
手元にいつも使ってる電卓がないので、
double の中身を覗いていました。
1 #include <stdio.h>
2
3 int main()
4 {
5 >...int i;
6 >...double d = 8.04;
7 >...unsigned char *p = (unsigned char *) &d;
8
9 >...for (i = 0; i < sizeof(d); ++i)
10 >...>...printf("%1x ", *p++);
11
12 >...printf("\n");
13
14 >...return 0;
15 }
実行結果は、40 20 14 7a e1 47 ae 14 となりました。
うまく表現できている場合には、40 21 0 0 0 0 0 0 (これは、8.5)
のように 0 が続くはずなんですが、8.04 はそうではないですね。
ということは、つまり、double では、8.04 という値は*表現できない*
ということです。
これは、10 進数では、1/3 が何桁有効桁数があっても、
表現できないのと同じです。
PHP の浮動小数点形式は、IEEE 形式だと思いますが、
このあたりが参考になるかもしれません。
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vccore/html/_core_ieee_floating.2d.point_representation_and_microsoft_languages.asp
結論として、浮動小数点形式による演算は「誤差あり」演算ですので、
結果が自分の必要な精度が確保できているか、常に気を配る必要があり、
すくなくとも、消費税の計算さえまともにできない可能性があることを
考慮する必要があります。
--
Osamu Shigematsu <m5issige@mr.hitachi-medical.co.jp>