【问题标题】:Error in float to long conversion [duplicate]浮点到长转换错误[重复]
【发布时间】:2014-04-08 11:26:08
【问题描述】:

我猜这是由于浮点数和准确性,但我只是想检查以确保我没有遗漏任何其他内容。

我有一个 1007.62 的浮点数(存储在 info.Amount 中),它乘以 100 并转换为 long。此时我得到的值为 100761。

这只是我们在应用双精度时遇到的旧的舍入错误吗?我认为可能发生这种情况的唯一方法是,如果它实际上存储为 1007.6199999999999 (但出于显示目的四舍五入)。然后在乘法转换为 long 忽略小数点后的所有内容?

【问题讨论】:

标签: c#


【解决方案1】:

您可以改用Convert.ToInt64。这会产生正确的值。

LinqPad-测试代码:

float z = 1007.62f;
z.Dump();

float x = z *100;
x.Dump();

long l = (long) (z*100);
l.Dump();

l = Convert.ToInt64(z*100);
l.Dump();

l = Convert.ToInt64(x);
l.Dump();

结果是:

1007,62
100762
100761
100762
100762

强制转换 (long) (z*100) 使用 CIL 指令 conv.i8 转换为 Int64,将 Int64 压入堆栈,而 Convert.ToInt64 使用 Math.Round(double) 转换/强制转换为 Int64。

关于conv.i8的特别说明是

从浮点数转换为整数值会截断 数字趋近于零。

【讨论】:

  • 确实 - 这实际上是我选择的修复方法,正如您在我的屏幕截图中看到的那样,我检查了几种不同的方法。
  • @Ian,啊,好吧,我没在你的图片中注意到这一点。
【解决方案2】:

实际上我认为这是由于您可能声明的变量。

采取以下示例:

       double amount = 1007.62;
       long result = (long) (amount*100);

结果绝对是 100762,没有任何分数或圆度。事实上,1007.62 是一个双精度数,不应存储为浮点数,这可能会导致像您的情况这样的进一步问题。

【讨论】:

  • 可能是 - 该值实际上是通过除法计算的。我没有特别声明。
  • 您是否将您的财产 (info.Amount) 声明为 float 或 double?
猜你喜欢
  • 1970-01-01
  • 2015-06-01
  • 2013-07-07
  • 1970-01-01
  • 1970-01-01
  • 2014-11-10
  • 1970-01-01
  • 1970-01-01
  • 2021-08-09
相关资源
最近更新 更多