C# - 为什么要浮动。使用大数字(如 1000000000f)的 CompareTo() 无法按预期工作



为什么使用大数字float.CompareTo()不能按预期工作?

测试编号:

float a = 1000000000f;
float b = 1000000001f;
float c = 1000000002f;
float d = 999999999f;

结果:

a.CompareTo(a) = 0
a.CompareTo(b) = 0
a.CompareTo(c) = 0
a.CompareTo(d) = 0

文档说:

  • 小于零:此实例在排序顺序中位于 obj 之前。
  • 零:此实例在排序顺序中与 obj 相同的位置出现。
  • 大于零:此实例在排序顺序中跟随 obj。

正如你所看到的,结果显示a,b,c和d是相同的。

但是,如果我使用较小的数字,例如:

float a = 100000f;
float b = 100001f;
float c = 100002f;
float d = 99999f;

结果:

a.CompareTo(a) = 0
a.CompareTo(b) = -1
a.CompareTo(c) = -1
a.CompareTo(d) = 1

正确比较数字。

我读了浮点数学坏了吗?我理解十进制数字时的精度错误。但是为什么没有小数的大数字会产生这种意想不到的结果呢?

上下文。为什么使用比较?

我正在研究一些寻路算法,如BFS,Dijkstra和A *,我最终在我的PriorityQueue类中使用了IComparable,然后在测试时我遇到了错误。虽然我解决了算法中的所有错误,但我想知道为什么会发生这种情况。

编辑

我按照@GSerg的建议测试打印值,并收到了更多问题。a.ToString("N0")b.ToString("N0")c.ToString("N0")d.ToString("N0"),在第一种情况下,所有四个变量都打印:"1,000,000,000"。在第二种情况下,打印正确的较小数字。

据我了解,这种行为的原因是因为一个大的浮点数以类似"科学记数法"的样式存储,使它们的小数失去精度。浮点数学坏了吗?解释道。

这是因为浮点数可以表示从 −16,777,216 到 16,777,216 的整数值。 https://en.wikipedia.org/wiki/Single-precision_floating-point_format#Precision_limitations_on_integer_values

使用双精度时,您会得到预期的结果。

double a = 1000000000;
double b = 1000000001;
double c = 1000000002;
double d = 999999999;

相关内容

最新更新