📄 ieeefloat.c
字号:
if ('0' <= x && x <= '9') x -= '0'; else if ('a' <= x && x <= 'f') x = x - 'a' + 0xA; else if ('A' <= x && x <= 'F') x = x - 'A' + 0xA; else x = 0; return(x);}voidHex2Bytes(register char *hex, register char *bytes){ for ( ; *hex; hex += 2) { *bytes++ = (GetHexValue(hex[0]) << 4) | GetHexValue(hex[1]); if (hex[1] == 0) break; /* Guard against odd bytes */ }}intGetHexSymbol(register int x){ x &= 0xF; if (x <= 9) x += '0'; else x += 'A' - 0xA; return(x);}voidBytes2Hex(register char *bytes, register char *hex, register int nBytes){ for ( ; nBytes--; bytes++) { *hex++ = GetHexSymbol(*bytes >> 4); *hex++ = GetHexSymbol(*bytes); } *hex = 0;}voidMaybeSwapBytes(char* bytes, int nBytes){#ifdef LITTLE_ENDIAN register char *p, *q, t; for (p = bytes, q = bytes+nBytes-1; p < q; p++, q--) { t = *p; *p = *q; *q = t; }#else if (bytes, nBytes); /* Just so it's used */#endif /* LITTLE_ENDIAN */}floatMachineIEEESingle(char* bytes){ float t; MaybeSwapBytes(bytes, 4); t = *((float*)(bytes)); MaybeSwapBytes(bytes, 4); return (t);}DoubleMachineIEEEDouble(char* bytes){ Double t; MaybeSwapBytes(bytes, 8); t = *((Double*)(bytes)); MaybeSwapBytes(bytes, 8); return (t);}voidTestFromIeeeSingle(char *hex){ defdouble f; union SParts p; char bytes[4]; Hex2Bytes(hex, bytes); f = ConvertFromIeeeSingle(bytes); p.s = f;#ifdef IEEE fprintf(stderr, "IEEE(%g) [%s] --> float(%g) [%08lX]\n", MachineIEEESingle(bytes), hex, f, p.i);#else /* IEEE */ fprintf(stderr, "IEEE[%s] --> float(%g) [%08lX]\n", hex, f, p.i);#endif /* IEEE */}voidTestToIeeeSingle(defdouble f){ union SParts p; char bytes[4]; char hex[8+1]; p.s = f; ConvertToIeeeSingle(f, bytes); Bytes2Hex(bytes, hex, 4);#ifdef IEEE fprintf(stderr, "float(%g) [%08lX] --> IEEE(%g) [%s]\n", f, p.i, MachineIEEESingle(bytes), hex );#else /* IEEE */ fprintf(stderr, "float(%g) [%08lX] --> IEEE[%s]\n", f, p.i, hex);#endif /* IEEE */}voidTestFromIeeeDouble(char *hex){ defdouble f; union DParts p; char bytes[8]; Hex2Bytes(hex, bytes); f = ConvertFromIeeeDouble(bytes); p.d = f;#ifdef IEEE fprintf(stderr, "IEEE(%g) [%.8s %.8s] --> double(%g) [%08lX %08lX]\n", MachineIEEEDouble(bytes), hex, hex+8, f, p.i[0], p.i[1]);#else /* IEEE */ fprintf(stderr, "IEEE[%.8s %.8s] --> double(%g) [%08lX %08lX]\n", hex, hex+8, f, p.i[0], p.i[1]);#endif /* IEEE */}voidTestToIeeeDouble(defdouble f){ union DParts p; char bytes[8]; char hex[16+1]; p.d = f; ConvertToIeeeDouble(f, bytes); Bytes2Hex(bytes, hex, 8);#ifdef IEEE fprintf(stderr, "double(%g) [%08lX %08lX] --> IEEE(%g) [%.8s %.8s]\n", f, p.i[0], p.i[1], MachineIEEEDouble(bytes), hex, hex+8 );#else /* IEEE */ fprintf(stderr, "double(%g) [%08lX %08lX] --> IEEE[%.8s %.8s]\n", f, p.i[0], p.i[1], hex, hex+8 );#endif /* IEEE */}voidTestFromIeeeExtended(char *hex){ defdouble f; union EParts p; char bytes[12]; Hex2Bytes(hex, bytes); f = ConvertFromIeeeExtended(bytes); p.e = f; bytes[11] = bytes[9]; bytes[10] = bytes[8]; bytes[9] = bytes[7]; bytes[8] = bytes[6]; bytes[7] = bytes[5]; bytes[6] = bytes[4]; bytes[5] = bytes[3]; bytes[4] = bytes[2]; bytes[3] = 0; bytes[2] = 0;#if defined(applec) || defined(THINK_C) || defined(METROWERKS) fprintf(stderr, "IEEE(%g) [%.4s %.8s %.8s] --> extended(%g) [%04X %04X%04X %04X%04X]\n", *((defdouble*)(bytes)), hex, hex+4, hex+12, f, p.i[0]&0xFFFF, p.i[2]&0xFFFF, p.i[3]&0xFFFF, p.i[4]&0xFFFF, p.i[5]&0xFFFF );#else /* !Macintosh */ fprintf(stderr, "IEEE[%.4s %.8s %.8s] --> extended(%g) [%04X %04X%04X %04X%04X]\n", hex, hex+4, hex+12, f, p.i[0]&0xFFFF, p.i[2]&0xFFFF, p.i[3]&0xFFFF, p.i[4]&0xFFFF, p.i[5]&0xFFFF );#endif /* Macintosh */}voidTestToIeeeExtended(defdouble f){ char bytes[12]; char hex[24+1]; ConvertToIeeeExtended(f, bytes); Bytes2Hex(bytes, hex, 10); bytes[11] = bytes[9]; bytes[10] = bytes[8]; bytes[9] = bytes[7]; bytes[8] = bytes[6]; bytes[7] = bytes[5]; bytes[6] = bytes[4]; bytes[5] = bytes[3]; bytes[4] = bytes[2]; bytes[3] = 0; bytes[2] = 0;#if defined(applec) || defined(THINK_C) || defined(METROWERKS) fprintf(stderr, "extended(%g) --> IEEE(%g) [%.4s %.8s %.8s]\n", f, *((defdouble*)(bytes)), hex, hex+4, hex+12 );#else /* !Macintosh */ fprintf(stderr, "extended(%g) --> IEEE[%.4s %.8s %.8s]\n", f, hex, hex+4, hex+12 );#endif /* Macintosh */}#include <signal.h>void SignalFPE(int i, void (*j)()){ printf("[Floating Point Interrupt Caught.]\n", i, j); signal(SIGFPE, SignalFPE);}voidmain(void){ long d[3]; char bytes[12]; signal(SIGFPE, SignalFPE); TestFromIeeeSingle("00000000"); TestFromIeeeSingle("80000000"); TestFromIeeeSingle("3F800000"); TestFromIeeeSingle("BF800000"); TestFromIeeeSingle("40000000"); TestFromIeeeSingle("C0000000"); TestFromIeeeSingle("7F800000"); TestFromIeeeSingle("FF800000"); TestFromIeeeSingle("00800000"); TestFromIeeeSingle("00400000"); TestFromIeeeSingle("00000001"); TestFromIeeeSingle("80000001"); TestFromIeeeSingle("3F8FEDCB"); TestFromIeeeSingle("7FC00100"); /* Quiet NaN(1) */ TestFromIeeeSingle("7F800100"); /* Signalling NaN(1) */ TestToIeeeSingle(0.0); TestToIeeeSingle(-0.0); TestToIeeeSingle(1.0); TestToIeeeSingle(-1.0); TestToIeeeSingle(2.0); TestToIeeeSingle(-2.0); TestToIeeeSingle(3.0); TestToIeeeSingle(-3.0);#if !(defined(sgi) || defined(NeXT)) TestToIeeeSingle(HUGE_VAL); TestToIeeeSingle(-HUGE_VAL);#endif#ifdef IEEE /* These only work on big-endian IEEE machines */ d[0] = 0x00800000L; MaybeSwapBytes(d,4); TestToIeeeSingle(*((float*)(&d[0]))); /* Smallest normalized */ d[0] = 0x00400000L; MaybeSwapBytes(d,4); TestToIeeeSingle(*((float*)(&d[0]))); /* Almost largest denormalized */ d[0] = 0x00000001L; MaybeSwapBytes(d,4); TestToIeeeSingle(*((float*)(&d[0]))); /* Smallest denormalized */ d[0] = 0x00000001L; MaybeSwapBytes(d,4); TestToIeeeSingle(*((float*)(&d[0])) * 0.5); /* Smaller than smallest denorm */ d[0] = 0x3F8FEDCBL; MaybeSwapBytes(d,4); TestToIeeeSingle(*((float*)(&d[0])));#if !(defined(sgi) || defined(NeXT)) d[0] = 0x7FC00100L; MaybeSwapBytes(d,4); TestToIeeeSingle(*((float*)(&d[0]))); /* Quiet NaN(1) */ d[0] = 0x7F800100L; MaybeSwapBytes(d,4); TestToIeeeSingle(*((float*)(&d[0]))); /* Signalling NaN(1) */#endif /* sgi */#endif /* IEEE */ TestFromIeeeDouble("0000000000000000"); TestFromIeeeDouble("8000000000000000"); TestFromIeeeDouble("3FF0000000000000"); TestFromIeeeDouble("BFF0000000000000"); TestFromIeeeDouble("4000000000000000"); TestFromIeeeDouble("C000000000000000"); TestFromIeeeDouble("7FF0000000000000"); TestFromIeeeDouble("FFF0000000000000"); TestFromIeeeDouble("0010000000000000"); TestFromIeeeDouble("0008000000000000"); TestFromIeeeDouble("0000000000000001"); TestFromIeeeDouble("8000000000000001"); TestFromIeeeDouble("3FFFEDCBA9876543"); TestFromIeeeDouble("7FF8002000000000"); /* Quiet NaN(1) */ TestFromIeeeDouble("7FF0002000000000"); /* Signalling NaN(1) */ TestToIeeeDouble(0.0); TestToIeeeDouble(-0.0); TestToIeeeDouble(1.0); TestToIeeeDouble(-1.0); TestToIeeeDouble(2.0); TestToIeeeDouble(-2.0); TestToIeeeDouble(3.0); TestToIeeeDouble(-3.0);#if !(defined(sgi) || defined(NeXT)) TestToIeeeDouble(HUGE_VAL); TestToIeeeDouble(-HUGE_VAL);#endif#ifdef IEEE /* These only work on big-endian IEEE machines */ Hex2Bytes("0010000000000000", bytes); MaybeSwapBytes(d,8); TestToIeeeDouble(*((Double*)(bytes))); /* Smallest normalized */ Hex2Bytes("0010000080000000", bytes); MaybeSwapBytes(d,8); TestToIeeeDouble(*((Double*)(bytes))); /* Normalized, problem with unsigned */ Hex2Bytes("0008000000000000", bytes); MaybeSwapBytes(d,8); TestToIeeeDouble(*((Double*)(bytes))); /* Almost largest denormalized */ Hex2Bytes("0000000080000000", bytes); MaybeSwapBytes(d,8); TestToIeeeDouble(*((Double*)(bytes))); /* Denorm problem with unsigned */ Hex2Bytes("0000000000000001", bytes); MaybeSwapBytes(d,8); TestToIeeeDouble(*((Double*)(bytes))); /* Smallest denormalized */ Hex2Bytes("0000000000000001", bytes); MaybeSwapBytes(d,8); TestToIeeeDouble(*((Double*)(bytes)) * 0.5); /* Smaller than smallest denorm */ Hex2Bytes("3FFFEDCBA9876543", bytes); MaybeSwapBytes(d,8); TestToIeeeDouble(*((Double*)(bytes))); /* accuracy test */#if !(defined(sgi) || defined(NeXT)) Hex2Bytes("7FF8002000000000", bytes); MaybeSwapBytes(d,8); TestToIeeeDouble(*((Double*)(bytes))); /* Quiet NaN(1) */ Hex2Bytes("7FF0002000000000", bytes); MaybeSwapBytes(d,8); TestToIeeeDouble(*((Double*)(bytes))); /* Signalling NaN(1) */#endif /* sgi */#endif /* IEEE */ TestFromIeeeExtended("00000000000000000000"); /* +0 */ TestFromIeeeExtended("80000000000000000000"); /* -0 */ TestFromIeeeExtended("3FFF8000000000000000"); /* +1 */ TestFromIeeeExtended("BFFF8000000000000000"); /* -1 */ TestFromIeeeExtended("40008000000000000000"); /* +2 */ TestFromIeeeExtended("C0008000000000000000"); /* -2 */ TestFromIeeeExtended("7FFF0000000000000000"); /* +infinity */ TestFromIeeeExtended("FFFF0000000000000000"); /* -infinity */ TestFromIeeeExtended("7FFF8001000000000000"); /* Quiet NaN(1) */ TestFromIeeeExtended("7FFF0001000000000000"); /* Signalling NaN(1) */ TestFromIeeeExtended("3FFFFEDCBA9876543210"); /* accuracy test */ TestToIeeeExtended(0.0); TestToIeeeExtended(-0.0); TestToIeeeExtended(1.0); TestToIeeeExtended(-1.0); TestToIeeeExtended(2.0); TestToIeeeExtended(-2.0);#if !(defined(sgi) || defined(NeXT)) TestToIeeeExtended(HUGE_VAL); TestToIeeeExtended(-HUGE_VAL);#endif /* sgi */#if defined(applec) || defined(THINK_C) || defined(METROWERKS) Hex2Bytes("7FFF00008001000000000000", bytes); TestToIeeeExtended(*((long double*)(bytes))); /* Quiet NaN(1) */ Hex2Bytes("7FFF00000001000000000000", bytes); TestToIeeeExtended(*((long double*)(bytes))); /* Signalling NaN(1) */ Hex2Bytes("7FFE00008000000000000000", bytes); TestToIeeeExtended(*((long double*)(bytes))); Hex2Bytes("000000008000000000000000", bytes); TestToIeeeExtended(*((long double*)(bytes))); Hex2Bytes("000000000000000000000001", bytes); TestToIeeeExtended(*((long double*)(bytes))); Hex2Bytes("3FFF0000FEDCBA9876543210", bytes); TestToIeeeExtended(*((long double*)(bytes)));#endif}/* This is the output of the test program on an IEEE machine:IEEE(0) [00000000] --> float(0) [00000000]IEEE(-0) [80000000] --> float(-0) [80000000]IEEE(1) [3F800000] --> float(1) [3F800000]IEEE(-1) [BF800000] --> float(-1) [BF800000]IEEE(2) [40000000] --> float(2) [40000000]IEEE(-2) [C0000000] --> float(-2) [C0000000]IEEE(INF) [7F800000] --> float(INF) [7F800000]IEEE(-INF) [FF800000] --> float(-INF) [FF800000]IEEE(1.17549e-38) [00800000] --> float(1.17549e-38) [00800000]IEEE(5.87747e-39) [00400000] --> float(5.87747e-39) [00400000]IEEE(1.4013e-45) [00000001] --> float(1.4013e-45) [00000001]IEEE(-1.4013e-45) [80000001] --> float(-1.4013e-45) [80000001]IEEE(1.12444) [3F8FEDCB] --> float(1.12444) [3F8FEDCB]IEEE(NAN(001)) [7FC00100] --> float(INF) [7F800000]IEEE(NAN(001)) [7F800100] --> float(INF) [7F800000]float(0) [00000000] --> IEEE(0) [00000000]float(-0) [80000000] --> IEEE(0) [00000000]float(1) [3F800000] --> IEEE(1) [3F800000]float(-1) [BF800000] --> IEEE(-1) [BF800000]float(2) [40000000] --> IEEE(2) [40000000]float(-2) [C0000000] --> IEEE(-2) [C0000000]float(3) [40400000] --> IEEE(3) [40400000]float(-3) [C0400000] --> IEEE(-3) [C0400000]float(INF) [7F800000] --> IEEE(INF) [7F800000]float(-INF) [FF800000] --> IEEE(-INF) [FF800000]float(1.17549e-38) [00800000] --> IEEE(1.17549e-38) [00800000]float(5.87747e-39) [00400000] --> IEEE(5.87747e-39) [00400000]float(1.4013e-45) [00000001] --> IEEE(1.4013e-45) [00000001]float(7.00649e-46) [00000000] --> IEEE(0) [00000000]float(1.12444) [3F8FEDCB] --> IEEE(1.12444) [3F8FEDCB]float(NAN(001)) [7FC00100] --> IEEE(INF) [7F800000]float(NAN(001)) [7FC00100] --> IEEE(INF) [7F800000]IEEE(0) [00000000 00000000] --> double(0) [00000000 00000000]IEEE(-0) [80000000 00000000] --> double(-0) [80000000 00000000]IEEE(1) [3FF00000 00000000] --> double(1) [3FF00000 00000000]IEEE(-1) [BFF00000 00000000] --> double(-1) [BFF00000 00000000]IEEE(2) [40000000 00000000] --> double(2) [40000000 00000000]IEEE(-2) [C0000000 00000000] --> double(-2) [C0000000 00000000]IEEE(INF) [7FF00000 00000000] --> double(INF) [7FF00000 00000000]IEEE(-INF) [FFF00000 00000000] --> double(-INF) [FFF00000 00000000]IEEE(2.22507e-308) [00100000 00000000] --> double(2.22507e-308) [00100000 00000000]IEEE(1.11254e-308) [00080000 00000000] --> double(1.11254e-308) [00080000 00000000]IEEE(4.94066e-324) [00000000 00000001] --> double(4.94066e-324) [00000000 00000001]IEEE(-4.94066e-324) [80000000 00000001] --> double(-4.94066e-324) [80000000 00000001]IEEE(1.99556) [3FFFEDCB A9876543] --> double(1.99556) [3FFFEDCB A9876543]IEEE(NAN(001)) [7FF80020 00000000] --> double(INF) [7FF00000 00000000]IEEE(NAN(001)) [7FF00020 00000000] --> double(INF) [7FF00000 00000000]double(0) [00000000 00000000] --> IEEE(0) [00000000 00000000]double(-0) [80000000 00000000] --> IEEE(0) [00000000 00000000]double(1) [3FF00000 00000000] --> IEEE(1) [3FF00000 00000000]double(-1) [BFF00000 00000000] --> IEEE(-1) [BFF00000 00000000]double(2) [40000000 00000000] --> IEEE(2) [40000000 00000000]double(-2) [C0000000 00000000] --> IEEE(-2) [C0000000 00000000]double(3) [40080000 00000000] --> IEEE(3) [40080000 00000000]double(-3) [C0080000 00000000] --> IEEE(-3) [C0080000 00000000]double(INF) [7FF00000 00000000] --> IEEE(INF) [7FF00000 00000000]double(-INF) [FFF00000 00000000] --> IEEE(-INF) [FFF00000 00000000]double(2.22507e-308) [00100000 00000000] --> IEEE(2.22507e-308) [00100000 00000000]double(2.22507e-308) [00100000 80000000] --> IEEE(2.22507e-308) [00100000 80000000]double(1.11254e-308) [00080000 00000000] --> IEEE(1.11254e-308) [00080000 00000000]double(1.061e-314) [00000000 80000000] --> IEEE(1.061e-314) [00000000 80000000]double(4.94066e-324) [00000000 00000001] --> IEEE(4.94066e-324) [00000000 00000001]double(4.94066e-324) [00000000 00000001] --> IEEE(4.94066e-324) [00000000 00000001]double(1.99556) [3FFFEDCB A9876543] --> IEEE(1.99556) [3FFFEDCB A9876543]double(NAN(001)) [7FF80020 00000000] --> IEEE(INF) [7FF00000 00000000]double(NAN(001)) [7FF80020 00000000] --> IEEE(INF) [7FF00000 00000000]IEEE(0) [0000 00000000 00000000] --> extended(0) [0000 00000000 00000000]IEEE(-0) [8000 00000000 00000000] --> extended(-0) [8000 00000000 00000000]IEEE(1) [3FFF 80000000 00000000] --> extended(1) [3FFF 80000000 00000000]IEEE(-1) [BFFF 80000000 00000000] --> extended(-1) [BFFF 80000000 00000000]IEEE(2) [4000 80000000 00000000] --> extended(2) [4000 80000000 00000000]IEEE(-2) [C000 80000000 00000000] --> extended(-2) [C000 80000000 00000000]IEEE(INF) [7FFF 00000000 00000000] --> extended(INF) [7FFF 00000000 00000000]IEEE(-INF) [FFFF 00000000 00000000] --> extended(-INF) [FFFF 00000000 00000000]IEEE(NAN(001)) [7FFF 80010000 00000000] --> extended(INF) [7FFF 00000000 00000000]IEEE(NAN(001)) [7FFF 00010000 00000000] --> extended(INF) [7FFF 00000000 00000000]IEEE(1.99111) [3FFF FEDCBA98 76543210] --> extended(1.99111) [3FFF FEDCBA98 76543210]extended(0) --> IEEE(0) [0000 00000000 00000000]extended(-0) --> IEEE(0) [0000 00000000 00000000]extended(1) --> IEEE(1) [3FFF 80000000 00000000]extended(-1) --> IEEE(-1) [BFFF 80000000 00000000]extended(2) --> IEEE(2) [4000 80000000 00000000]extended(-2) --> IEEE(-2) [C000 80000000 00000000]extended(INF) --> IEEE(INF) [7FFF 00000000 00000000]extended(-INF) --> IEEE(-INF) [FFFF 00000000 00000000]extended(NAN(001)) --> IEEE(INF) [7FFF 00000000 00000000]extended(NAN(001)) --> IEEE(INF) [7FFF 00000000 00000000]extended(5.94866e+4931) --> IEEE(5.94866e+4931) [7FFE 80000000 00000000]extended(1e-4927) --> IEEE(1e-4927) [0000 80000000 00000000]extended(1e-4927) --> IEEE(1e-4927) [0000 00000000 00000001]extended(1.99111) --> IEEE(1.99111) [3FFF FEDCBA98 76543210]*/#endif /* TEST_FP */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -