/* int および long long int の評価 double および long double の評価 */ #include #include /* int と long long int 型の乗算オーバーフローの確認 */ void ev_int() { int i; printf(" * size of int %d\n", sizeof(int)); printf(" * range of int\n"); i = 0xf0000000; do { i *= 2; printf("%d\n", i); } while (i < 0); long long int li; printf("\n * size of long long int %d\n", sizeof(long long int)); printf(" * range of long long int\n"); li = 0xf000000000000000LL; /* LL, ULL */ while (li != 0) { li *= 2; printf("%qd\n", li); /* "Ld" do not work. "lld" works. */ } while (li < 0LL); printf("\n"); } /* double のふるまい !isnormal(d) do not work well. 原因未追究。 see : http://www.gnu.org/manual/glibc-2.2.5/html_node/Floating-Point-Classes.html#Floating%20Point%20Classes */ void ev_dbl() { int i, c; double d, m; printf(" * size of double %d\n", sizeof(double)); printf(" * large exponent of double\n"); /* 指数部が大きいとき */ d = 8e307; m = exp(log(2.0) / 4); for (i = 0; i < 20; i += 1) { d *= m; c = __fpclassifyd(d); printf("%16.8g class %d\n", d, c); if (c != FP_NORMAL) break; } printf("\n"); printf(" * small exponent of double (1)\n"); /* 指数部が小さいとき */ d = 5e-308; m = exp(-log(2.0) / 4); for (i = 0; i < 20; i += 1) { d *= m; c = __fpclassifyd(d); printf("%16.8g class %d\n", d, c); if (c != FP_NORMAL) break; } printf("\n"); printf(" * small exponent of double (2)\n"); /* 指数部が、もっと小さいとき */ d = 5e-323; m = 0.5; for (i = 0; i < 20; i += 1) { d *= m; c = __fpclassifyd(d); printf("%16.8g class %d\n", d, c); if (c != FP_SUBNORMAL) break; } printf("\n"); printf(" * mantissa precision of double\n"); /* 仮数部の精度 */ d = 0.1; m = 10; for (i = 0; i < 40; i += 1) { d *= m; printf("%32.24e\n", d); } printf("\n"); } /* long double のふるまい */ void ev_ldbl() { int i; long double ld, lm; printf(" * size of long double %d\n", sizeof(long double)); printf(" * mantissa precision of long double\n"); /* 仮数部の精度 */ ld = 0.1; lm = 10; for (i = 0; i < 40; i += 1) { ld *= lm; printf("%32.24Le\n", ld); } printf("\n"); printf(" * large exponent of long double\n"); /* 指数部が大きいとき */ ld = 1e4929L; lm = 10; for (i = 0; i < 5; i += 1) { ld *= lm; printf("%16.8Le\n", ld); } printf("\n"); printf(" * small exponent of long double\n"); /* 指数部が小さいとき */ ld = 1e-4939L; lm = 1.0/10; for (i = 0; i < 15; i += 1) { ld *= lm; printf("%16.8Le\n", ld); } printf("\n"); } int main(int argc, char* argv[]) { ev_int(); ev_dbl(); ev_ldbl(); return 0; }