很抱歉提出这样的初学者问题,但我无法弄明白。
我有一个长整数,我想将其除以1.28,然后将其向上或向下舍入到最接近的整数。
long size = 24524343254;
double ratio = 1.28;
size = size * 1.28; //Error Cannot implicitly convert type 'double' to 'long'
答案 0 :(得分:5)
您需要将double结果显式地转换为long(因为编译器声明没有隐式转换:
size = (long)Math.Round(size * 1.28);
如果你想要舍入到最近,你需要Math.Round
(有一个特殊情况,当圆的数字在两个数字之间的中间时,它会向默认的四舍五入舍入)。如果您只希望向0舍入,则可以将结果简单地转换回(long)(size * 1.28)
。
正如@CodeInChaos所指出的,从long到double(size * 1.28
的隐式强制转换会将大小转换为双精度)会导致精度损失为doubles only have a precision of 53 bits但长为64位。
答案 1 :(得分:2)
你应该把结果投射得很长。
size = (long)Math.Round(size * 1.28);
答案 2 :(得分:2)
您还可以考虑使用decimal
。
size = (long)Math.Round(size * 1.28m);//note the m making the literal a decimal.
在这种情况下,这比double
提供了两个优势:
decimal
可以精确地表示每个long
值(与double
不同,只有53个尾数位,十进制有> 90个尾数位,足以表示由long
)你还应该确保MidpointRounding.ToEven
对你没问题。它将1.5
舍入为2
,但将0.5
舍入为0
。
如果值超出Decimal
的范围,long
投放到long
时会导致异常。
使用double
溢出行为取决于模式。如果您在checked
部分,它将抛出异常,在unchecked
上下文中将导致未定义的值。由于很少需要未定义的值,因此我建议将checked
与double
一起使用:
size = checked((long)Math.Round(size * 1.28));