關於浮點數轉換為整數的測試
阿新 • • 發佈:2019-02-03
#include <stdio.h>
int main(void) {
float flt = 1.116533e24f;
printf("%e\n", flt);
printf("%ld\n", (long)flt); /* wrong */
printf("%u\n", *(unsigned long * const)&flt); /* 將浮點數理解為整數 */
return 0;
}
/* * 浮點數和整數強制型別轉換的模擬測試 */ #include <stdio.h> typedef int int32_t; typedef unsigned uint32_t; typedef unsigned char uint8_t; static int32_t float_to_int32(float flt) { uint32_t ret; uint8_t e; ret = (*(uint32_t * const)&flt) & 0x007FFFFF; /* 取23位尾數 */ e = (uint8_t)((*(uint32_t * const)&flt) >> 23); /* 取8位階碼 */ if (ret == 0u) { if (e == 0u) return 0; else if (e == 0xFF) { puts("inf"); return 0xFFFFFFFF; } } else { if (e == 0xFF) { puts("NaN"); return 0; } } ret |= 0x00800000; /* 寫入隱藏位1 */ if (e >= 150u) ret <<= e - 150u; else ret >>= 150u - e; if ((*(uint32_t * const)&flt) >> 31) /* 判斷符號位 */ ret = -ret; /* 使用一元運算子 */ return (int32_t)ret; } static float int32_to_float(int32_t s32) { uint32_t tmp; uint8_t cnt; if (s32 == 0) return 0.0f; if ((uint32_t)s32 >> 31) tmp = -s32; else tmp = s32; while (tmp) { tmp >>= 1; cnt++; } if ((uint32_t)s32 >> 31) tmp = -s32; else tmp = s32; if (cnt > 24u) tmp >>= cnt - 24u; else tmp <<= 24u - cnt; tmp &= 0xFF7FFFFF; tmp |= (uint32_t)(cnt - 1u + 127u) << 23u; if ((uint32_t)s32 >> 31) /* 寫入符號位 */ tmp |= 0x80000000; return *(float * const)&tmp; } int main(void) { float f = -3451.987f; /* 不要超過int32_t的表示範圍 */ int32_t s32 = -1234567; /* 不要超過float的7位精度 */ printf("%d\n", (int32_t)f); printf("%d\n", float_to_int32(f)); printf("%f\n", (float)s32); printf("%f\n", int32_to_float(s32)); return 0; }