【问题标题】:How to Multiply Long by Double如何将 Long 乘以 Double
【发布时间】:2012-03-10 22:23:59
【问题描述】:

很抱歉问了这么一个初学者的问题,但我想不通。

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

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

【问题讨论】:

  • 您要执行哪种类型的舍入?
  • 您的文字和您的代码不一致。文字说除法,代码确实乘法。
  • 请不要在问题的末尾添加“C#”之类的内容。这就是标签的用途。

标签: c# double rounding long-integer multiplication


【解决方案1】:

您需要将双精度结果显式转换回 long(如编译器所述 - 没有隐式转换):

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

如果你想四舍五入到最近,你需要Math.Round(当要四舍五入的数字在两个数字之间时有一种特殊情况,那么即使默认情况下也会向最近的数字四舍五入)。如果您只想向 0 舍入,也可以简单地将结果转换回 (long)(size * 1.28)

正如@CodeInChaos 所指出的,从 long 到 double 的隐式转换(size * 1.28 将首先将 size 转换为 double)可能导致精度损失,因为 doubles only have a precision of 53 bits 但 long 是 64 位。

【讨论】:

  • Math.Round 默认使用银行家四舍五入(四舍五入到最接近的偶数)。
  • @Cameron:这仅适用于中点舍入(1.1 仍舍入为 1 而不是 2
  • 值得注意的是,从longdouble 的隐式转换是有损的。 double 有 53 个尾数位,而 long 有 63 个。
  • @ChrisWue:是的;我的评论具有误导性!不过,了解这一点很重要。
  • 非常感谢你们。像魅力一样工作!
【解决方案2】:

你应该尽可能长地转换结果。

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

【讨论】:

  • 那不做四舍五入。
【解决方案3】:

您也可以考虑使用decimal

size = (long)Math.Round(size * 1.28m);//note the m making the literal a decimal.

在这种情况下,这比 double 有两个优势:

  • decimal 可以精确表示每一个long 值(不像double 只有53 个尾数位,十进制有>90 个尾数位,足以表示long 使用的63 位)
  • 它可以精确地表示 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));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-12
    • 1970-01-01
    • 2013-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多