You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#浮点数计算精度问题:result_2值异常原因咨询

Why does (int)(num * test) return 207 instead of 208 in C#?

这个问题的核心在于浮点数的精度限制以及C#表达式求值时的临时精度处理,咱们一步步拆解:

首先看你的复现代码:

int num = 160; 
float test = 1.3f; 
float result = num * test; 
int result_1 = (int)result; 
int result_2 = (int)(num * test); 
int result_3 = (int)(float)(num * test); 
Console.WriteLine("{0} {1} {2} {3}", result, result_1, result_2, result_3);

运行输出:208 208 207 208

1. 为什么1.3f无法精确表示?

二进制浮点数(比如float)没法精确存储所有十进制小数,1.3就是典型案例。1.3f在内存里实际是一个略小于1.3的近似值——它的二进制展开是无限循环的,只能截断到float的24位有效精度,实际值约为1.2999999523162841796875。

2. 分析result和result_1

计算num * test(160 × 1.3f)的实际数学结果是160 × 1.2999999523162841796875 = 207.99999237060546875。
当你把这个值赋值给float result时,float的精度只能保留6-7位有效数字。207.99999237...和208极其接近,float无法区分二者的差异,所以会被舍入为208.0f。
因此(int)result直接取整就得到了208。

3. 为什么result_2是207?

这里的关键是表达式求值的临时精度处理:C#在计算num * test时,编译器可能会用比float更高的精度(比如double)来存储中间结果——double有53位有效精度,能精确保留207.99999237060546875这个值,不会像float那样舍入成208。
当你直接对这个高精度临时值执行(int)强制转换时,C#会截断小数部分(不是四舍五入),所以207.99999237...就变成了207。

4. 为什么result_3又回到208?

(int)(float)(num * test)的过程是:先把num * test的高精度中间值转换为float——这一步和赋值给result时的逻辑一样,会把207.99999237...舍入为208.0f,再强制转换为int,自然得到208。

总结一下:

  • 当结果被存储到float变量时,精度限制会让近似值舍入到最近的可表示float值(208)。
  • 当直接对表达式的临时结果转换为int时,更高精度的中间值保留了“略小于208”的细节,截断后得到207。

内容的提问来源于stack exchange,提问作者tkokof

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:28:37