C#:将带有浮点数的表达式转换为 int 时的错误结果
C#: Wrong result when converting expression with floats to int
取下面的代码:
float a = 100.0f;
float b = 0.05f;
如果我想将a
和b
相除的结果转换为一个整数,我可以用这个代码来完成:
float c = a / (b * 1000.0f); // c = 2f
int res = (int)c; // res = 2
但是我想减少代码行数,所以我更喜欢使用这段代码:
int res = (int)(a / (b * 1000.0f)); // Here we are --> res = 1 !
为什么最后一个代码我得到的是 res = 1
而不是 res = 2
?
编译器在计算某些表达式时使用额外的精度。在 C# language specification 中,条款 9.3.7 允许实现在浮点表达式中使用比结果类型更高的精度:
Floating-point operations may be performed with higher precision than the result type of the operation.
注意.05f
的值为0.0500000007450580596923828125。当以 float
精度计算 .05f * 1000.0f
时,由于四舍五入,结果为 50。但是,当以 double
或更高精度计算时,结果为 50.0000007450580596923828125。然后用 double
精度除以 100 得到 1.999999970197678056393897350062616169452667236328125。当这个转换为int
时,结果是1.
在float c = a / (b * 1000.0f);
中,除法的结果转为float
。即使以 double
精度计算除法并产生 1.999999970197678056393897350062616169452667236328125,此值在舍入为 float
时变为 2,因此 c
设置为 2。
在int res = (int)(a / (b * 1000.0f));
中,除法结果不转换为float
。如果编译器以 double
精度计算它,则结果为 1.999999970197678056393897350062616169452667236328125,转换结果为 1.
取下面的代码:
float a = 100.0f;
float b = 0.05f;
如果我想将a
和b
相除的结果转换为一个整数,我可以用这个代码来完成:
float c = a / (b * 1000.0f); // c = 2f
int res = (int)c; // res = 2
但是我想减少代码行数,所以我更喜欢使用这段代码:
int res = (int)(a / (b * 1000.0f)); // Here we are --> res = 1 !
为什么最后一个代码我得到的是 res = 1
而不是 res = 2
?
编译器在计算某些表达式时使用额外的精度。在 C# language specification 中,条款 9.3.7 允许实现在浮点表达式中使用比结果类型更高的精度:
Floating-point operations may be performed with higher precision than the result type of the operation.
注意.05f
的值为0.0500000007450580596923828125。当以 float
精度计算 .05f * 1000.0f
时,由于四舍五入,结果为 50。但是,当以 double
或更高精度计算时,结果为 50.0000007450580596923828125。然后用 double
精度除以 100 得到 1.999999970197678056393897350062616169452667236328125。当这个转换为int
时,结果是1.
在float c = a / (b * 1000.0f);
中,除法的结果转为float
。即使以 double
精度计算除法并产生 1.999999970197678056393897350062616169452667236328125,此值在舍入为 float
时变为 2,因此 c
设置为 2。
在int res = (int)(a / (b * 1000.0f));
中,除法结果不转换为float
。如果编译器以 double
精度计算它,则结果为 1.999999970197678056393897350062616169452667236328125,转换结果为 1.