如何乘双倍乘

时间:2012-03-10 22:23:59

标签: c# double rounding long-integer multiplication

很抱歉提出这样的初学者问题,但我无法弄明白。

我有一个长整数,我想将其除以1.28,然后将其向上或向下舍入到最接近的整数。

long size = 24524343254;
double ratio = 1.28;
size = size * 1.28; //Error Cannot implicitly convert type 'double' to 'long'

3 个答案:

答案 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
  • 它可以完全代表1.28。

你还应该确保MidpointRounding.ToEven对你没问题。它将1.5舍入为2,但将0.5舍入为0

如果值超出Decimal的范围,long投放到long时会导致异常。

使用double溢出行为取决于模式。如果您在checked部分,它将抛出异常,在unchecked上下文中将导致未定义的值。由于很少需要未定义的值,因此我建议将checkeddouble一起使用:

size = checked((long)Math.Round(size * 1.28));