Loading... # 什么是浮点数? 浮点数就是用来表示**小数**(实数)的数据类型。让我用通俗易懂的方式解释: ## 什么是浮点数? **浮点数 = 科学计数法的二进制版本** 就像我们写很大的数会用科学计数法: - 1,200,000 = 1.2 × 10⁶ - 0.000012 = 1.2 × 10⁻⁵ 计算机用类似的方法表示小数,但是使用**二进制**。 ## 浮点数的组成 浮点数由三部分组成(以32位float为例): ``` [符号位] [指数部分] [小数部分] 1位 8位 23位 ``` **举例:** 数字 `-13.625` 在计算机中如何表示? 1. **符号位**:负号 → 1 2. **转换为二进制**: - 整数部分:13 = 1101(二进制) - 小数部分:0.625 = 0.101(二进制) - 合并:13.625 = 1101.101(二进制) 3. **科学计数法**:1101.101 = 1.101101 × 2³ - 小数部分:1.101101 → 去掉前面的1,得到 101101 - 指数部分:3 ## 为什么叫"浮点数"? "浮点"的意思是**小数点的位置可以浮动**: ```c // 这些数都是浮点数,小数点位置不同 float a = 123.45; // 小数点在第3位后 float b = 1.2345; // 小数点在第1位后 float c = 12345.0; // 小数点在第5位后 ``` ## 浮点数的实际问题 ```c #include <stdio.h> int main() { // 问题1:有些十进制小数无法精确表示为二进制小数 float f = 0.1f; // 0.1在十进制中很简单,但在二进制中是无限循环的! printf("0.1 的实际存储值: %.20f\n", f); // 问题2:连续相加会产生误差 float sum = 0.0f; for (int i = 0; i < 10; i++) { sum += 0.1f; } printf("0.1相加10次: %.10f\n", sum); // 可能不是精确的1.0 return 0; } ``` ## 生活中的类比 **想象一把尺子:** - **整数**:只能量整厘米(1cm, 2cm, 3cm...) - **浮点数**:可以量毫米(1.1cm, 1.2cm, 1.25cm...),但精度有限 **关键点:** 1. 浮点数不是绝对精确的(就像尺子有最小刻度) 2. 表示范围很大,可以表示非常小或非常大的数 3. 运算可能产生微小误差 ## 编程中的浮点数类型 ```c #include <stdio.h> #include <float.h> int main() { printf("float 精度: 约%d位有效数字\n", FLT_DIG); printf("double 精度: 约%d位有效数字\n", DBL_DIG); printf("float 范围: %e 到 %e\n", FLT_MIN, FLT_MAX); printf("double 范围: %e 到 %e\n", DBL_MIN, DBL_MAX); return 0; } ``` **简单总结:** 浮点数就是计算机用来表示小数的近似方法,虽然不完美,但足够应对大多数科学计算和工程应用的需求。 # 经典疑问 ## float 和 double 的区别 | 特性 | float | double | |------|-------|--------| | 大小 | 4字节 (32位) | 8字节 (64位) | | 精度 | 约6-7位有效数字 | 约15-16位有效数字 | | 范围 | ±3.4e-38 到 ±3.4e+38 | ±1.7e-308 到 ±1.7e+308 | | 关键字 | `float` | `double` | ## printf 中的格式说明符 ```c #include <stdio.h> int main() { float f = 3.141592653589793f; // 注意后面的 f double d = 3.141592653589793; // 正确的格式说明符 printf("float: %f\n", f); // 默认显示6位小数 printf("double: %lf\n", d); // %lf 用于 double // 控制小数位数 printf("float(2位): %.2f\n", f); printf("double(4位): %.4lf\n", d); // 科学计数法表示 printf("科学计数法: %e\n", f); printf("科学计数法: %le\n", d); return 0; } ``` ## 浮点数的玄学问题 ```c #include <stdio.h> #include <math.h> int main() { // 问题1:精度损失 float a = 0.1f; float b = 0.2f; float c = a + b; printf("0.1 + 0.2 = %.10f\n", c); // 可能不是精确的 0.3 // 问题2:比较浮点数不要直接用 == if (fabs(c - 0.3f) < 1e-6) { // 使用误差范围比较 printf("c ≈ 0.3\n"); } // 问题3:大数吃小数 float big = 1e8f; float small = 1.0f; printf("大数 + 小数 = %f\n", big + small); // 可能还是 100000000 return 0; } ``` ## 四舍五入的正确用法 ```c #include <stdio.h> #include <math.h> int main() { double numbers[] = {3.4, 3.5, 3.6, -2.3, -2.7}; int size = sizeof(numbers) / sizeof(numbers[0]); printf("四舍五入示例:\n"); for (int i = 0; i < size; i++) { printf("%.1f -> %.0f\n", numbers[i], round(numbers[i])); } // 其他相关的舍入函数 double x = 2.7; printf("\n其他舍入函数:\n"); printf("round(%.1f) = %.0f (四舍五入)\n", x, round(x)); printf("ceil(%.1f) = %.0f (向上取整)\n", x, ceil(x)); printf("floor(%.1f) = %.0f (向下取整)\n", x, floor(x)); printf("trunc(%.1f) = %.0f (向零取整)\n", x, trunc(x)); return 0; } ``` 最后修改:2025 年 09 月 30 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏