很长一段时间以来,我一直认为浮点运算是明确定义的,不同的平台进行相同的计算应得到相同的结果。 (给定相同的舍入模式。)
然而Microsoft's SQL Server deems any calculation performed with floating point to have an "imprecise" result,意味着你不能拥有它的索引。这告诉我,微软的人认为有一个关于浮点的相关问题。
那捕获的是什么?
编辑:您可以在浮点数上使用索引,而不是在计算列上。此外,地理数据使用浮点类型作为坐标,这些也明显被索引。因此,这不是一般可靠比较的问题。
答案 0 :(得分:4)
浮点运算由IEEE 754标准明确定义。在您指出的文档中,Microsoft显然没有选择遵守该标准。
有许多问题使得浮点重现性变得困难,您可以通过搜索“[floating-point] reproducibility”找到有关它们的Stack Overflow讨论。但是,大多数这些问题都是关于高级语言缺乏控制(单个浮点运算完全可以重现并由IEEE 754指定,并且硬件提供了足够的IEEE 754一致性,但是高级语言规范没有充分地将语言结构映射到特定的浮点运算),数学库例程中的差异(诸如sin
和log
之类的函数在某种意义上是“难”计算的,并且供应商在没有调用的情况下实现它们正确的舍入,因此每个供应商的例程与其他例程的错误特征略有不同),多线程和其他问题允许以不同的顺序执行操作,从而产生不同的结果,等等。
在Microsoft的SQL Server这样的单一系统中,如果他们愿意,微软可能会控制这些问题。但仍有一些问题需要考虑。例如,数据库系统可能具有sum
函数,用于计算许多事物的总和。对于速度,您可能希望sum
实现具有以任何顺序添加元素的灵活性,以便它可以利用多处理或以它们碰巧存储的任何顺序添加元素。但是添加使用相同浮点格式的基本加法运算的浮点数据具有不同的结果,具体取决于元素的顺序。要使总和可重现,您必须指定操作顺序或使用额外的精度或其他技术,然后性能受损。
因此,不进行浮点运算是一个选择,而不是浮点运算缺乏规范的结果。
数据库目的的另一个问题是,即使定义良好且完全指定的浮点算法也具有NaN值。 (NaN,Not a Number的缩写,表示不是数字的浮点数据。由于没有数学结果的操作(例如负数的实平方根)而产生NaN。 NaN充当占位符,以便浮点运算可以继续而不会中断,并且应用程序可以完成一组浮点运算,然后采取措施来替换或以其他方式处理所出现的任何NaN。)因为NaN不代表数字,它不等于任何东西,甚至不是自己。比较两个NaN的相等性会产生错误,即使NaN用完全相同的位表示。这是数据库的问题,因为NaN不能用作查找记录的键,因为NaN搜索键永远不会等于记录的键字段中的NaN。有时这是通过定义两个不同的排序关系来处理的 - 一个是通常的数学比较,它定义小于,等于和大于数字(并且对于NaNs,所有三个都是假的),第二个定义了排序顺序,并为所有数据定义,包括NaN。
应该注意的是,每个不是NaN的浮点数据代表一定数量完全。浮点数没有不精确性。浮点数不表示间隔。浮点操作近似实数算术,因为它们返回的值大致等于精确的数学结果,而浮点数精确。 IEEE 754准确指定了基本的浮点运算。在使用不同的操作(包括使用不同精度的相同操作),使用不同顺序的操作或使用不符合IEEE 754标准的操作时,会出现重复性不足的情况