📄 ieeefloat.c
字号:
long expon;
unsigned long hiMant, loMant;
#ifdef TEST
printf("ConvertFromIEEEExtended(%lx,%lx,%lx,%lx,%lx,%lx,%lx,%lx,%lx,%lx\r",
(long)bytes[0], (long)bytes[1], (long)bytes[2], (long)bytes[3],
(long)bytes[4], (long)bytes[5], (long)bytes[6],
(long)bytes[7], (long)bytes[8], (long)bytes[9]);
#endif
expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
hiMant = ((unsigned long)(bytes[2] & 0xFF) << 24)
| ((unsigned long)(bytes[3] & 0xFF) << 16)
| ((unsigned long)(bytes[4] & 0xFF) << 8)
| ((unsigned long)(bytes[5] & 0xFF));
loMant = ((unsigned long)(bytes[6] & 0xFF) << 24)
| ((unsigned long)(bytes[7] & 0xFF) << 16)
| ((unsigned long)(bytes[8] & 0xFF) << 8)
| ((unsigned long)(bytes[9] & 0xFF));
if (expon == 0 && hiMant == 0 && loMant == 0) {
f = 0;
}
else {
if (expon == 0x7FFF) { /* Infinity or NaN */
f = HUGE_VAL;
}
else {
expon -= 16383;
f = ldexp(UnsignedToFloat(hiMant), expon-=31);
f += ldexp(UnsignedToFloat(loMant), expon-=32);
}
}
if (bytes[0] & 0x80)
return -f;
else
return f;
}
//=======================================================
// Function name: ConvertToIeeeExtended
// Author:
// Date: 2002/3/27
// Description:
// Input:
// Return value:
// Update:
// Date Name Description
// ========== ================== ======================
//2002/3/27
//=======================================================
void ConvertToIeeeExtended(defdouble num, char *bytes)
{
int sign;
int expon;
defdouble fMant, fsMant;
unsigned long hiMant, loMant;
if (num < 0) {
sign = 0x8000;
num *= -1;
} else {
sign = 0;
}
if (num == 0) {
expon = 0; hiMant = 0; loMant = 0;
}
else {
fMant = frexp(num, &expon);
if ((expon > 16384) || !(fMant < 1)) { /* Infinity or NaN */
expon = sign|0x7FFF; hiMant = 0; loMant = 0; /* infinity */
}
else { /* Finite */
expon += 16382;
if (expon < 0) { /* denormalized */
fMant = ldexp(fMant, expon);
expon = 0;
}
expon |= sign;
fMant = ldexp(fMant, 32); fsMant = floor(fMant); hiMant = FloatToUnsigned(fsMant);
fMant = ldexp(fMant - fsMant, 32); fsMant = floor(fMant); loMant = FloatToUnsigned(fsMant);
}
}
bytes[0] = expon >> 8;
bytes[1] = expon;
bytes[2] = hiMant >> 24;
bytes[3] = hiMant >> 16;
bytes[4] = hiMant >> 8;
bytes[5] = hiMant;
bytes[6] = loMant >> 24;
bytes[7] = loMant >> 16;
bytes[8] = loMant >> 8;
bytes[9] = loMant;
}
/****************************************************************
* Testing routines for the floating-point conversions.
****************************************************************/
#ifdef METROWERKS
#define IEEE
#endif
#ifdef applec
# define IEEE
#endif /* applec */
#ifdef THINK_C
# define IEEE
#endif /* THINK_C */
#ifdef sgi
# define IEEE
#endif /* sgi */
#ifdef sequent
# define IEEE
# define LITTLE_ENDIAN
#endif /* sequent */
#ifdef sun
# define IEEE
#endif /* sun */
#ifdef NeXT
# define IEEE
#endif /* NeXT */
#ifdef MAIN
union SParts {
Single s;
long i;
};
union DParts {
Double d;
long i[2];
};
union EParts {
defdouble e;
short i[6];
};
//=======================================================
// Function name: GetHexValue
// Author:
// Date: 2002/3/27
// Description:
// Input:
// Return value:
// Update:
// Date Name Description
// ========== ================== ======================
//2002/3/27
//=======================================================
int GetHexValue(register int x)
{
x &= 0x7F;
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);
}
//=======================================================
// Function name: Hex2Bytes
// Author:
// Date: 2002/3/27
// Description:
// Input:
// Return value:
// Update:
// Date Name Description
// ========== ================== ======================
//2002/3/27
//=======================================================
void Hex2Bytes(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 */
}
}
//=======================================================
// Function name: GetHexSymbol
// Author:
// Date: 2002/3/27
// Description:
// Input:
// Return value:
// Update:
// Date Name Description
// ========== ================== ======================
//2002/3/27
//=======================================================
int GetHexSymbol(register int x)
{
x &= 0xF;
if (x <= 9)
x += '0';
else
x += 'A' - 0xA;
return(x);
}
//=======================================================
// Function name: Bytes2Hex
// Author:
// Date: 2002/3/27
// Description:
// Input:
// Return value:
// Update:
// Date Name Description
// ========== ================== ======================
//2002/3/27
//=======================================================
void Bytes2Hex(register char *bytes, register char *hex, register int nBytes)
{
for ( ; nBytes--; bytes++) {
*hex++ = GetHexSymbol(*bytes >> 4);
*hex++ = GetHexSymbol(*bytes);
}
*hex = 0;
}
//=======================================================
// Function name: MaybeSwapBytes
// Author:
// Date: 2002/3/27
// Description:
// Input:
// Return value:
// Update:
// Date Name Description
// ========== ================== ======================
//2002/3/27
//=======================================================
void MaybeSwapBytes(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 */
}
//=======================================================
// Function name: MachineIEEESingle
// Author:
// Date: 2002/3/27
// Description:
// Input:
// Return value:
// Update:
// Date Name Description
// ========== ================== ======================
//2002/3/27
//=======================================================
float MachineIEEESingle(char *bytes)
{
float t;
MaybeSwapBytes(bytes, 4);
t = *((float*)(bytes));
MaybeSwapBytes(bytes, 4);
return (t);
}
//=======================================================
// Function name: MachineIEEEDouble
// Author:
// Date: 2002/3/27
// Description:
// Input:
// Return value:
// Update:
// Date Name Description
// ========== ================== ======================
//2002/3/27
//=======================================================
Double MachineIEEEDouble(char *bytes)
{
Double t;
MaybeSwapBytes(bytes, 8);
t = *((Double*)(bytes));
MaybeSwapBytes(bytes, 8);
return (t);
}
//=======================================================
// Function name: TestFromIeeeSingle
// Author:
// Date: 2002/3/27
// Description:
// Input:
// Return value:
// Update:
// Date Name Description
// ========== ================== ======================
//2002/3/27
//=======================================================
void TestFromIeeeSingle(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 */
}
//=======================================================
// Function name: TestToIeeeSingle
// Author:
// Date: 2002/3/27
// Description:
// Input:
// Return value:
// Update:
// Date Name Description
// ========== ================== ======================
//2002/3/27
//=======================================================
void TestToIeeeSingle(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 */
}
//=======================================================
// Function name: TestFromIeeeDouble
// Author:
// Date: 2002/3/27
// Description:
// Input:
// Return value:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -