前提・実現したいこと
double型の内部表現を明らかにし、誤差に対する理解を深める目的でdouble型をビット単位で表示する関数を
ウェブサイトを参考にしながら作りました。(https://www.k-cube.co.jp/wakaba/server/floating_point.html)
double型の10.1, 10.2, 20.3をそれぞれビット表示し、誤差が原因で10.1 + 10.2 != 20.3であることを確認しました。
そして、計算機イプシロンを左辺に加えることで両辺のビット表示が同じになることを確認し、それらを比較演算したところ、予想に反し、両辺の値が違うという結果が出ました。
どのようなことが起こっているのか教えていただけるとありがたいです。
該当のソースコード
C
1#include <stdio.h> 2#include <float.h> 3 4void dump(unsigned char *p); 5 6void main() { 7 8 double x, y, z; 9 x = 10.1; 10 y = 10.2; 11 z = 20.3; 12 union { 13 double d; 14 unsigned char c[8]; 15 } uni; 16 17 uni.d = x + y; 18 printf(" x + y: "); 19 dump(uni.c); 20 21 uni.d = DBL_EPSILON + x + y; 22 printf("eps + x + y: "); 23 dump(uni.c); 24 25 uni.d = z; 26 printf(" z: "); 27 dump(uni.c); 28 29 if (DBL_EPSILON + x + y != z) 30 puts("eps + x + y != z"); 31} 32void dump(unsigned char *p) { 33 int i, j; 34 35 //p[7]から下ってアクセスしていく 36 for (i = 7; i >= 0; i--) { 37 38 //1バイトを2進数表示する 39 for (j = 7; j >= 0; j--) { 40 printf("%d", (p[i] >> j) % 2); 41 } 42 putchar(' '); 43 } 44 putchar('\n'); 45}
実行結果
x + y: 01000000 00110100 01001100 11001100 11001100 11001100 11001100 11001100 eps + x + y: 01000000 00110100 01001100 11001100 11001100 11001100 11001100 11001101 z: 01000000 00110100 01001100 11001100 11001100 11001100 11001100 11001101 eps + x + y != z
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/06/06 10:51
2020/06/06 14:03