请使用以下代码:
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节允许实现在浮点表达式中使用比结果类型更高的精度:
可以以比操作的结果类型更高的精度执行浮点运算。
请注意,.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。