采用以下代码:
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
?
答案 0 :(得分:3)
在计算某些表达式时,编译器使用额外的精度。在C# language specification中,第9.3.7节允许实现在浮点表达式中使用比结果类型更高的精度:
浮点运算的执行精度可能高于运算的结果类型。
请注意,.05f
的值为0.0500000007450580596923828125。当.05f * 1000.0f
的精度为float
时,由于舍入,结果为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。