小數部分直接截斷 (向零取整),不進行四捨五入。
float f = 123.99f;
int i = (int)f; // 結果:123 (非 124)
float f2 = -123.99f;
int i2 = (int)f2; // 結果:-123 (非 -124)
當有限浮點值轉換為整數類型時,**小數部分被丟棄** (即向零截斷)。如果整數部分超出目標類型範圍,行為未定義。
| 浮點值 | (int)截斷 | round()四捨五入 | floor()向下取整 | ceil()向上取整 | trunc()向零取整 |
|---|---|---|---|---|---|
| 3.14 | 3 | 3 | 3 | 4 | 3 |
| 3.99 | 3 | 4 | 3 | 4 | 3 |
| -3.14 | -3 | -3 | -4 | -3 | -3 |
| -3.99 | -3 | -4 | -4 | -3 | -3 |
| 0.0 | 0 | 0 | 0 | 0 | 0 |
<math.h>,編譯鏈接 -lm)#include <math.h>
int main() {
double x = 3.14159;
long i_trunc = (long)trunc(x); // 3 向零截斷 (C99)
long i_floor = (long)floor(x); // 3 向下取整
long i_ceil = (long)ceil(x); // 4 向上取整
long i_round = (long)round(x); // 3 四捨五入 (半數遠離零)
long i_lround = lround(x); // 3 直接返回 long (C99)
long i_rint = (long)rint(x); // 3 按當前舍入模式 (通常銀行家舍入)
// 最近整數,返回浮點數
double n = nearbyint(x); // 3.0
double r = rint(x); // 3.0
return 0;
}
float huge = 1e30f;
int i = (int)huge; // UB!int 通常最大 21億,結果不可預測
// 安全做法
if (huge > INT_MAX || huge < INT_MIN) {
// 處理溢出
} else {
int i = (int)huge;
}
float f = 0.1f + 0.2f; // 0.300000012
int i = (int)(f * 10); // 預期 3,實際可能 3 或 2!
// 金融/精度敏感領域:使用定點數、整數分或 decimal 庫
int i1 = (int)NAN; // UB
int i2 = (int)INFINITY; // UB
// 必須先檢查 isfinite()
// 向零截斷 (模擬 (int)float)
int float_to_int_trunc(float f) {
if (f >= 0) return (int)f; // 正數直接截斷
// 負數:利用 IEEE 754 特性或轉換
return -(int)(-f); // 注意 -INT_MIN 溢出
}
// 四捨五入
int float_to_int_round(float f) {
return (int)(f >= 0 ? f + 0.5f : f - 0.5f);
}
// 定點數 Q16.16 示例
typedef int32_t fixed16_16;
#define TO_FIXED(x) ((fixed16_16)((x) * 65536.0f))
#define TO_FLOAT(x) ((float)(x) / 65536.0f)
// 避免類型遊弄導致 UB
// 錯誤:
float f = 3.14f;
int i = *(int*)&f; // 違反嚴格別名規則,UB!
// 正確:使用聯合體 (C99 允許) 或 memcpy
union { float f; int i; } u;
u.f = 3.14f;
int bits = u.i; // 獲取 IEEE 754 位模式
// 或標準庫
#include <string.h>
int bits;
memcpy(&bits, &f, sizeof(float));
(int)f 進行截斷,語義清晰、編譯器優化最好lround() / round() + 範圍檢查isfinite() 並確保在目標類型範圍內