/*********************************************************************** Report sizeof() values, and the machine epsilon and smallest floating-point number, to investigate floating-point support. [21-Nov-2001] ***********************************************************************/ #include #include #include float fstore(float x) { return (x); } double dstore(double x) { return (x); } #if defined(HAVE_LONGDOUBLE) long double ldstore(long double x) { return (x); } long double fppow2(int n) { long double x, power; x = (n < 0) ? (1.0L/2.0L) : 2.0L; n = (n < 0) ? -n : n; power = 1.0L; while (n-- > 0) power *= x; return (power); } #else double fppow2(int n) { double x, power; x = (n < 0) ? (1.0L/2.0L) : 2.0L; n = (n < 0) ? -n : n; power = 1.0L; while (n-- > 0) power *= x; return (power); } #endif void test_float(void) { float x; (void)printf("float:\n"); (void)printf("\tsizeof(float) = %2u\n", (unsigned int)sizeof(float)); (void)printf("\tFLT_MANT_DIG = %2d\n", FLT_MANT_DIG); x = 1.0F; while (fstore(1.0F + x/2.0F) != 1.0F) x /= 2.0F; (void)printf("\tmachine epsilon = %13.5e ", x); if (x == (float)fppow2(-23)) (void)printf("[IEEE 754 32-bit macheps]\n"); else (void)printf("[not IEEE 754 conformant]\n"); x = 1.0F; while (fstore(x / 2.0F) != 0.0F) x /= 2.0F; (void)printf("\tsmallest positive number = %13.5e ", x); if (x == (float)fppow2(-149)) (void)printf("[IEEE 754 smallest 32-bit subnormal]\n"); else if (x == (float)fppow2(-126)) (void)printf("[IEEE 754 smallest 32-bit normal]\n"); else (void)printf("[not IEEE 754 conformant]\n"); (void)printf("\n"); } void test_double(void) { double x; (void)printf("double:\n"); (void)printf("\tsizeof(double) = %2u\n", (unsigned int)sizeof(double)); (void)printf("\tDBL_MANT_DIG = %2d\n", DBL_MANT_DIG); x = 1.0; while (dstore(1.0 + x/2.0) != 1.0) x /= 2.0; (void)printf("\tmachine epsilon = %13.5le ", x); if (x == (double)fppow2(-52)) (void)printf("[IEEE 754 64-bit macheps]\n"); else (void)printf("[not IEEE 754 conformant]\n"); x = 1.0; while (dstore(x / 2.0) != 0.0) x /= 2.0; (void)printf("\tsmallest positive number = %13.5le ", x); if (x == (double)fppow2(-1074)) (void)printf("[IEEE 754 smallest 64-bit subnormal]\n"); else if (x == (double)fppow2(-1022)) (void)printf("[IEEE 754 smallest 64-bit normal]\n"); else (void)printf("[not IEEE 754 conformant]\n"); (void)printf("\n"); } void test_long_double(void) { #if defined(HAVE_LONGDOUBLE) long double x; (void)printf("long double:%s\n", (sizeof(double) == sizeof(long double)) ? " [**WARNING**: long double is really double]" : ""); (void)printf("\tsizeof(long double) = %2u\n", (unsigned int)sizeof(long double)); (void)printf("\tLDBL_MANT_DIG = %2d\n", LDBL_MANT_DIG); x = 1.0L; while (ldstore(1.0L + x/2.0L) != 1.0L) x /= 2.0L; (void)printf("\tmachine epsilon = %13.5Le ", x); if (x == (long double)fppow2(-52)) (void)printf("[IEEE 754 64-bit macheps]\n"); else if (x == (long double)fppow2(-63)) (void)printf("[IEEE 754 80-bit macheps]\n"); else if (x == (long double)fppow2(-112)) (void)printf("[IEEE 754 128-bit macheps]\n"); else (void)printf("[not IEEE 754 conformant]\n"); x = 1.0L; while (ldstore(x / 2.0L) != 0.0L) x /= 2.0L; (void)printf("\tsmallest positive number = %13.5Le ", x); #if LDBL_MANT_DIG == 53 if (x == (long double)fppow2(-1074)) (void)printf("[IEEE 754 smallest 64-bit subnormal]\n"); else if (x == (long double)fppow2(-1022)) (void)printf("[IEEE 754 smallest 64-bit normal]\n"); else (void)printf("[not IEEE 754 conformant]\n"); #elif LDBL_MANT_DIG == 64 if (x == (long double)fppow2(-16446)) (void)printf("[IEEE 754 smallest 80-bit subnormal]\n"); else if (x == (long double)fppow2(-16382)) (void)printf("[IEEE 754 smallest 80-bit normal]\n"); else (void)printf("[not IEEE 754 conformant]\n"); #elif LDBL_MANT_DIG == 113 if (x == (long double)fppow2(-16494)) (void)printf("[IEEE 754 smallest 128-bit subnormal]\n"); else if (x == (long double)fppow2(-16382)) (void)printf("[IEEE 754 smallest 128-bit normal]\n"); else (void)printf("[not IEEE 754 conformant]\n"); #else (void)printf("[not IEEE 754 conformant]\n"); #endif #endif (void)printf("\n"); } int main(int argc, char* argv[]) { test_float(); test_double(); test_long_double(); return (EXIT_SUCCESS); }