Floating point 为什么在执行精确任务时,浮点型优先于长型?

Floating point 为什么在执行精确任务时,浮点型优先于长型?,floating-point,int,long-integer,precision,floating-accuracy,Floating Point,Int,Long Integer,Precision,Floating Accuracy,为什么精度更喜欢浮点数?难道不能用非常大的整数来表示浮点运算给出的精度,并且在所有机器上都是确定性的吗?例如,浮点移动0.48124米的对象可以用int或long移动48124微米的对象来表示。它应该是481.24毫米,这是问题出现的部分原因。使用整数或长整数,很可能会遇到某种舍入情况。也许你的程序会保证你关心的最小单位是毫米,但它仍然会导致书写单位的标准有点难看。不难看出100000毫米==100米,但100.000并不明显,在一个应用程序中,你可能主要处理米或公里,但你仍然需要精度,阅读起来

为什么精度更喜欢浮点数?难道不能用非常大的整数来表示浮点运算给出的精度,并且在所有机器上都是确定性的吗?例如,浮点移动0.48124米的对象可以用int或long移动48124微米的对象来表示。

它应该是481.24毫米,这是问题出现的部分原因。使用整数或长整数,很可能会遇到某种舍入情况。也许你的程序会保证你关心的最小单位是毫米,但它仍然会导致书写单位的标准有点难看。不难看出100000毫米==100米,但100.000并不明显,在一个应用程序中,你可能主要处理米或公里,但你仍然需要精度,阅读起来比3463.823要烦人得多


此外,在很多情况下,您确实关心的是尺寸,而不是不方便的小尺寸,虽然使用浮点数可以减少显示的位数,但数据仍然存在,因此,3.141592653等等,无论浮点精度调整到3.14米,都比3141592653纳米容易处理。它将是481.24毫米,这是问题出现的部分原因。使用整数或长整数,很可能会遇到某种舍入情况。也许你的程序会保证你关心的最小单位是毫米,但它仍然会导致书写单位的标准有点难看。不难看出100000毫米==100米,但100.000并不明显,在一个应用程序中,你可能主要处理米或公里,但你仍然需要精度,阅读起来比3463.823要烦人得多


此外,在很多情况下,您确实关心的是尺寸,而不是不方便的小尺寸,虽然使用浮点数可以减少显示的位数,但数据仍然存在,因此,3.141592653等等,无论浮点精度调整到3.14米,都比3141592653纳米容易处理。在某些计算中,浮点优于整数,因为:

当您以定点格式乘法时,乘积有一个新的刻度,因此必须对其进行调整,或者必须编写代码以说明更改的刻度。例如,如果您采用按100缩放的格式,因此.3用30表示,而.4用40表示,那么将30乘以40将生成1200,但相同比例下的正确答案应为12表示.12。该司需要进行类似的调整。 当整数格式溢出时,许多机器和编程语言无法很好地支持获取结果的最重要部分。浮点自动产生结果的最高有效部分,并舍入丢弃的位。 整数运算通常会截断分数,但除非另有要求,否则浮点运算会将分数舍入。 有些计算涉及大量数字,包括非常大和非常小的数字。定点格式的范围较小,而浮点格式的范围较大。您可以使用定点格式手动跟踪刻度,但是您只需要使用整数实现自己的浮点。 许多机器和/或编程语言忽略整数溢出,但浮点可以优雅地处理这些溢出和/或在发生时提供通知。 浮点运算定义良好,通常实现良好;有时痛苦的经历会减少其中的bug。构建新的自己动手算法容易出现错误。 对于某些函数,很难预先预测结果的规模,因此使用定点格式很难。例如,考虑正弦。当输入接近π的倍数时,正弦接近零。因为π是无理的和超越的,所以整数或不动点数接近π的倍数的模式是非常不规则的。有些定点数不接近π的倍数,它们的正弦值在.1、.5、.9左右,等等。有些定点数非常接近π的倍数,它们的正弦值接近于零。一些非常接近π的倍数,它们的正弦很小。因此,没有一种具有合理精度的定点格式可以始终返回正弦结果,而不会出现下溢或溢出。 你问的是浮点型还是长型。在某些情况下,64位整数可能比32位浮点格式有优势,但通常适当的比较是针对可比较的大小,例如32位整数到32位浮点和64位整数到64位浮点。在t
在这些情况下,问题在于动态刻度的好处是否大于几位精度的损失。

在某些计算中,浮点优于整数,因为:

当您以定点格式乘法时,乘积有一个新的刻度,因此必须对其进行调整,或者必须编写代码以说明更改的刻度。例如,如果您采用按100缩放的格式,因此.3用30表示,而.4用40表示,那么将30乘以40将生成1200,但相同比例下的正确答案应为12表示.12。该司需要进行类似的调整。 当整数格式溢出时,许多机器和编程语言无法很好地支持获取结果的最重要部分。浮点自动产生结果的最高有效部分,并舍入丢弃的位。 整数运算通常会截断分数,但除非另有要求,否则浮点运算会将分数舍入。 有些计算涉及大量数字,包括非常大和非常小的数字。定点格式的范围较小,而浮点格式的范围较大。您可以使用定点格式手动跟踪刻度,但是您只需要使用整数实现自己的浮点。 许多机器和/或编程语言忽略整数溢出,但浮点可以优雅地处理这些溢出和/或在发生时提供通知。 浮点运算定义良好,通常实现良好;有时痛苦的经历会减少其中的bug。构建新的自己动手算法容易出现错误。 对于某些函数,很难预先预测结果的规模,因此使用定点格式很难。例如,考虑正弦。当输入接近π的倍数时,正弦接近零。因为π是无理的和超越的,所以整数或不动点数接近π的倍数的模式是非常不规则的。有些定点数不接近π的倍数,它们的正弦值在.1、.5、.9左右,等等。有些定点数非常接近π的倍数,它们的正弦值接近于零。一些非常接近π的倍数,它们的正弦很小。因此,没有一种具有合理精度的定点格式可以始终返回正弦结果,而不会出现下溢或溢出。 你问的是浮点型还是长型。在某些情况下,64位整数可能比32位浮点格式有优势,但通常适当的比较是针对可比较的大小,例如32位整数到32位浮点和64位整数到64位浮点。在这些情况下,问题在于动态刻度的好处是否大于几位精度的损失。

确定性行为的程度与数据表示无关。与整数数学相比,精确定义浮点数学只需要更长的规范,实现起来更复杂

IEEE浮点力求使浮点在所有机器上都具有确定性

整数可以是1或2的补码,并且具有不同的宽度,因此对于某些计算来说是不确定的。因此,整数数学本身可以解决许多问题

是的,大整数是可以的,并且已经按照OP的建议使用了。但正如@Eric Postphil所指出的,F-P的好处是多方面的。大整数用于特定情况,包括加密

关注即将推出的十进制浮点标准,以处理银行业务等问题。

确定性行为的程度与数据表示无关。与整数数学相比,精确定义浮点数学只需要更长的规范,实现起来更复杂

IEEE浮点力求使浮点在所有机器上都具有确定性

整数可以是1或2的补码,并且具有不同的宽度,因此对于某些计算来说是不确定的。因此,整数数学本身可以解决许多问题

是的,大整数是可以的,并且已经按照OP的建议使用了。但正如@Eric Postphil所指出的,F-P的好处是多方面的。大整数用于特定情况,包括加密


关注即将推出的十进制浮点标准,以处理银行业务等问题。

尽管许多代码可以比浮点更有效地使用某种固定值,但不同类型的代码和不同的情况有不同的要求。有些情况需要存储从零到一百万的数字,精确到千分之一;另一些则需要存储从零到一的数字,精确到十亿分之一。对于某些目的来说,几乎不足以满足的固定点格式对于其他目的来说将是极大的过度使用。如果一种语言能够有效地支持处理以多种不同格式存储的数字,请修复
ed point数学可以有一些非常巨大的优势。另一方面,对于一种语言来说,支持一到三种浮点格式通常比支持许多必要的定点格式更容易。此外,除非一种语言使单个例程能够处理各种定点格式,否则使用通用数学例程往往很困难。也许编译器技术已经发展到可以使用各种各样的定点类型,但硬件浮点技术已经发展到可以在很大程度上消除这种需要。

尽管许多代码可以比浮点更有效地使用某种固定值,不同类型的代码和不同的情况有不同的要求。有些情况需要存储从零到一百万的数字,精确到千分之一;另一些则需要存储从零到一的数字,精确到十亿分之一。对于某些目的来说,几乎不足以满足的固定点格式对于其他目的来说将是极大的过度使用。如果一种语言能够有效地支持处理以各种不同格式存储的数字,那么定点数学可以有一些非常巨大的优势。另一方面,对于一种语言来说,支持一到三种浮点格式通常比支持许多必要的定点格式更容易。此外,除非一种语言使单个例程能够处理各种定点格式,否则使用通用数学例程往往很困难。也许编译器技术已经发展到可以使用各种各样的定点类型,但硬件浮点技术已经发展到可以在很大程度上消除这种需要。

事实上,在某些应用程序中,出于许多原因,整数是首选的。特别是,整数与浮点不同,是平移不变的:

x1 - x2 == (x1 - displacement) - (x2 - displacement)
0.0002 - 0.0001 != (0.0002 - 1000000) - (0.0002 - 1000000) // this example in single precision
这在某些几何发动机中非常重要。例如,如果您正在计算由某个参数确定的相同形状组成的大型网格,那么您将计算相同参数集,并为每个参数集计算其一个代表图形中发生的情况,并将结果复制到具有相同参数的其他形状。平移不变性确保了这种优化是忠实的

另一方面,浮点不是平移不变的:

x1 - x2 == (x1 - displacement) - (x2 - displacement)
0.0002 - 0.0001 != (0.0002 - 1000000) - (0.0002 - 1000000) // this example in single precision

这有时会导致难以调试的异常情况。

事实上,在某些应用程序中,出于许多原因,整数是首选的。特别是,整数与浮点不同,是平移不变的:

x1 - x2 == (x1 - displacement) - (x2 - displacement)
0.0002 - 0.0001 != (0.0002 - 1000000) - (0.0002 - 1000000) // this example in single precision
这在某些几何发动机中非常重要。例如,如果您正在计算由某个参数确定的相同形状组成的大型网格,那么您将计算相同参数集,并为每个参数集计算其一个代表图形中发生的情况,并将结果复制到具有相同参数的其他形状。平移不变性确保了这种优化是忠实的

另一方面,浮点不是平移不变的:

x1 - x2 == (x1 - displacement) - (x2 - displacement)
0.0002 - 0.0001 != (0.0002 - 1000000) - (0.0002 - 1000000) // this example in single precision

这有时会导致难以调试的非常令人不快的意外情况。

1您永远不会有精确的0.48124000000000000。。。米。测量在某种程度上本质上是不精确的,并且该程度总是远小于双精度浮点数所代表的0.48124米==481.24毫米==481240微米。事实上,你在谈论这是一个多么好的想法时把转换搞砸了,这是一个与实践背道而驰的观点。1你永远不会有精确的0.48124000000000000。。。米。测量在某种程度上本质上是不精确的,并且该程度总是远小于双精度浮点数所代表的0.48124米==481.24毫米==481240微米。你在谈论一个多么好的想法时把转换搞砸了,这是一个反对实践的观点。手动刻度管理引入了浮点运算中不存在的错误源。@PatriciaShanahan:补充。我总体上同意,但想补充一点,sin的讨论是正确的,但不是那么强烈。如果要对角度使用定点数学,通常会跳转到度、梯度、BAMs等,而不是弧度。因此,精度问题得到了很好的控制。除了非常接近零的x值外,在-2+1范围内有一个固定的点值。我要添加到这一分析中的唯一一点是@cHao在对问题的评论中提出的观点。手动刻度管理引入了浮点运算中不存在的错误源。@PatriciaShanahan:补充。我总体上同意,但想补充一点,sin的讨论是正确的,但不是那么强烈。如果要对角度使用定点数学,通常
跳到度、梯度、BAMs等,而不是弧度。因此,精度问题得到了很好的控制。除了非常接近零的x值外,实际上-2浮点范围内的固定点值在同一台机器上是不确定的,更不用说不同的机器了。两个相同的程序,一个用-fast_数学优化编译,另一个用w/out编译,将产生不同的结果。原因是:IEEE标准非常激进,遵循它会将浮点计算速度降低10倍。这就是为什么许多应用程序更喜欢足够好和足够快,而不是符合IEEE标准且速度极其缓慢的原因,它们只是不向用户宣传这一点。特别是,许多GPU甚至不提供IEEE兼容选项,它们总是等效于-fast_math进行编译。@Michael FP可能在许多甚至大多数CPU上都不兼容,但这并不是因为FP本身不能兼容,而是具有挑战性。通常,正如你所说,目标是速度超过确定性行为——我同意。不提供符合IEEE标准的FP的编译器是一项业务决策,并不是说它不能做到。速度问题不是由软件驱动的,而是由FP硬件驱动的。如前所述,IEEE的复杂性令人困惑,一旦硬件制造完成,任何不合规行为确实会导致最坏情况下的性能提高10倍,但这肯定不是平均增长。你希望如此。在下面的链接中查看性能问题或IEEE denorm部分:在大多数现代CPU上,最坏情况的惩罚超过100倍。事实上,在早期的奔腾上,最糟糕的性能损失大约是250倍。为什么呢?对于一个小小的itsy bitsy双关语来说,预期的精度增益仅适用于非常接近零的数字?我所知道的所有corse编译器都提供了一个选项来禁用这种疯狂行为,大多数应用程序都乐于使用这个选项。这使得许多计算速度大大加快,但代价是尽量减少不符合IEEE标准的情况。@Michael我不知道有任何桌面平台默认将非规范化刷新为零。而且option-fast math明确表示要破坏标准遵从性,因此它破坏标准遵从性也就不足为奇了。浮点在实践中是确定的,除非您选择使其不可靠,这可能是一些人的最佳选择,但与此答案并不矛盾。Pascal、Nvidia GPU默认做许多非IEEE的事情,包括除法和sqrt降低1位精度、demorm刷新、,GPU阵列是科学计算的主要计算硬件,因为它们速度非常快。实际上,浮点运算在同一台机器上是不确定的,更不用说不同的机器了。两个相同的程序,一个用-fast_数学优化编译,另一个用w/out编译,将产生不同的结果。原因是:IEEE标准非常激进,遵循它会将浮点计算速度降低10倍。这就是为什么许多应用程序更喜欢足够好和足够快,而不是符合IEEE标准且速度极其缓慢的原因,它们只是不向用户宣传这一点。特别是,许多GPU甚至不提供IEEE兼容选项,它们总是等效于-fast_math进行编译。@Michael FP可能在许多甚至大多数CPU上都不兼容,但这并不是因为FP本身不能兼容,而是具有挑战性。通常,正如你所说,目标是速度超过确定性行为——我同意。不提供符合IEEE标准的FP的编译器是一项业务决策,并不是说它不能做到。速度问题不是由软件驱动的,而是由FP硬件驱动的。如前所述,IEEE的复杂性令人困惑,一旦硬件制造完成,任何不合规行为确实会导致最坏情况下的性能提高10倍,但这肯定不是平均增长。你希望如此。在下面的链接中查看性能问题或IEEE denorm部分:在大多数现代CPU上,最坏情况的惩罚超过100倍。事实上,在早期的奔腾上,最糟糕的性能损失大约是250倍。为什么呢?对于一个小小的itsy bitsy双关语来说,预期的精度增益仅适用于非常接近零的数字?我所知道的所有corse编译器都提供了一个选项来禁用这种疯狂行为,大多数应用程序都乐于使用这个选项。这使得许多计算速度大大加快,但代价是尽量减少不符合IEEE标准的情况。@Michael我不知道有任何桌面平台默认将非规范化刷新为零。而且option-fast math明确表示要破坏标准遵从性,因此它破坏标准遵从性也就不足为奇了。浮点在实践中是确定的,除非您选择使其不可靠,这可能是一些人的最佳选择,但与此答案并不矛盾。Pascal、Nvidia GPU默认做许多非IEEE的事情,包括除法和sqrt降低1位精度、demorm刷新、,GPU阵列是科学计算的主要计算硬件,因为它们的速度非常快。整数可以进行转换
依赖,但浮点数比整数更接近于与比例无关。还要注意的是,即使是整数数学也往往不像人们所希望的那样具有平移不变性,因为语言设计者认为定义运算符使a+b%b始终等于a%b并不重要。整数与平移无关,但浮点数比整数更接近于标度无关。还要注意的是,即使是整数数学也往往不像人们所希望的那样具有平移不变性,因为语言设计者认为定义运算符使a+b%b始终等于a%b并不重要。