【问题标题】:Cast double to long change the value将 double 转换为 long 更改值
【发布时间】:2019-10-08 09:34:56
【问题描述】:

我注意到从doublelong 的转换会在要转换的数字为时更改值,即使它远低于long最大值。 例如,有人能解释一下为什么这个转换没有按预期工作

Convert.ToInt64(600000000000040000d)
// Return => 600000000000039936
Convert.ToInt64(600000000000040000L)
// Return => 600000000000040000

这会给我的公式带来一些麻烦... 谢谢。

【问题讨论】:

标签: c# type-conversion double


【解决方案1】:

嗯,double尾数52只有(详见 https://en.wikipedia.org/wiki/Double-precision_floating-point_format);这就是为什么double 可以精确 表示最大为2**53 - 1 == 9007199254740991 的整数值。然而,

 600000000000040000 > 9007199254740991

这就是为什么舍入误差是不可避免的:

  double d = 600000000000040000d;

  long l = (long)d;

  double d2 = l;

  Console.WriteLine($"{d:r} : {l} : ({d == d2 ? "Equal" : "Different"})");

结果:

  6.0000000000004E+17 : 600000000000039936 : Equal

您可以尝试decimal 而不是double(尤其是如果您正在处理财务数据):

  decimal d = 600000000000040000m; // m suffix

  long l = (long)d;

  decimal d2 = l;

  Console.WriteLine($"{d} : {l} : ({d == d2 ? "Equal" : "Different"})");

结果:

  600000000000040000 : 600000000000040000 : Equal

【讨论】:

  • 这正是我想要的。十进制解决了我的问题,但更重要的是,我了解这种行为的原因。谢谢。
【解决方案2】:

我希望这对你有更多帮助。

// Double to long
           double av = 600000000000040000L;
            long lg = (long)av;
            long g1 = Convert.ToInt64(av);
// long to Double
            double dbl = (double)g1;
            double d = Convert.ToDouble(g1);

【讨论】:

    【解决方案3】:

    我希望这会有所帮助:

    当您将双精度或浮点值转换为整数类型时,该值会朝零四舍五入到最接近的整数值。如果生成的整数值超出目标类型的范围,则结果取决于溢出检查上下文。在已检查的上下文中,会引发 OverflowException,而在未检查的上下文中,结果是目标类型的未指定值。

    来源:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/explicit-numeric-conversions-table

    注意:Long 是整数类型,它是 Int64:In C# What's the difference between Int64 and long?

    此外,float 和 double 是带有浮点的类型。它们以不同的方式存储在内存中 How are floating point numbers stored in memory?

    维基百科:https://en.wikipedia.org/wiki/Single-precision_floating-point_format

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-23
      • 2021-12-03
      • 2013-01-20
      • 1970-01-01
      • 2014-02-02
      • 2014-09-30
      • 2019-05-20
      • 1970-01-01
      相关资源
      最近更新 更多