【问题标题】:C# strange precision lost int to float and backwardsC# 奇怪的精度丢失 int 到浮点和向后
【发布时间】:2018-11-23 13:09:28
【问题描述】:

当尝试从 int 转换为 float 和向后转换时会发生奇怪的事情。

原始示例代码:

int val = 28218681; // val=28218681

float fVal = (float) val; // fVal=2.821868E+07

int val2 = (int) fVal; // val2=28218680

有人可以解释为什么转化会从价值中丢失最右边的“1”吗?

谢谢你 马吕斯

【问题讨论】:

  • 我认为您可以在这里找到问题的答案,这是一种不同的语言,但适用的原则相同。 stackoverflow.com/questions/30260769/…
  • 见 - docs.microsoft.com/en-us/dotnet/csharp/language-reference/… - 注意精度是 "~6-9 位" 这意味着不是所有的 8 位整数都可以准确地表示为浮点数。
  • A floatint 都使用 32 位。但是,int 可以使用所有这些位来表示其符号和值,而 float 使用其中一些位来表示浮点和尾数,这意味着它不能表示相同范围的整数值 - 所以它失去了一些精度。
  • 不是答案,但如果你想要精确的分数,请使用小数而不是浮点数。
  • float 类型有 24 位可用于表示一个值,int 有 31 位。如此大的值无法拟合,必须四舍五入。第一次你会输一点是在 2^24+1 = 16777217,试试看。使用 double 来获得领先,它可以存储 53 位。或十进制,96 位,相当于 28 位十进制数字。

标签: c#


【解决方案1】:

这是对现已删除的答案的评论:

整数28218681可以用二进制写成1101011101001010100111001。请注意,需要 25 位数字。 Single precision 的“尾数”只有 24 位(包括隐式前导 1 位)。 24 小于 25。精度丢失。单精度表示仅通过前 24 位二进制数字“记住”一个数字。这对应于大约 7-8 个十进制数字。大致。整数28218681只有8位,问题就来了。


吸取的教训是,使用足够“宽”的类型以提供所需的精度。例如,double 精度数字可以保存数字的前 16 位小数。

这与使用二进制还是十进制格式的讨论无关。请注意,如果提问者使用decimal32 而不是binary32float 的另一个名称),他会遇到完全相同的问题!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-28
    • 1970-01-01
    • 2023-02-07
    • 2012-09-10
    • 2012-11-14
    相关资源
    最近更新 更多