浮点类型通过将有效数字及其指数分别存储在单独的二进制字中来表示数字,因此它适合16,32,64或128位。
固定点类型存储具有2个字的数字,一个表示整数部分,另一个表示基数超过基数的部分,在负指数中,2 ^ -1,2 ^ -2,2 ^ -3等。
Float更好,因为它们在指数意义上具有更宽的范围,但是如果想要在某个范围内以更高的精度存储数字,例如仅使用从-16到16的整数,则不会,因此使用更多位来保持数字超过基数。
在表现方面,哪一方表现最佳,或者有些情况下某些表现比其他表现更快?
在视频游戏编程中,每个人都使用浮点,因为FPU会让它更快,或者因为性能下降可以忽略不计,还是他们自己制作固定类型?
为什么C / C ++中没有固定类型?
答案 0 :(得分:5)
该定义涵盖了非常有限的定点实现子集。
更确切地说,在固定点上只存储尾数,指数是先验确定的常数。不需要二进制点落在尾数内,并且绝对不要求它落在单词边界上。例如,以下所有都是“固定点”:
GPU倾向于使用没有整数部分的固定点(通常是由2 -32 缩放的32位尾数)。因此,诸如OpenGL和Direct3D之类的API通常使用能够保存这些值的浮点类型。但是,操纵整数尾数通常更有效,因此这些API也允许以这种方式指定坐标(纹理空间,颜色空间等)。
至于你声称C ++没有固定点类型,我不同意。 C ++中的所有整数类型都是定点类型。通常假设指数为零,但这不是必需的,我用C ++以这种方式实现了相当多的定点DSP代码。
答案 1 :(得分:5)
在代码级别,定点算术只是带有隐含分母的整数算术。
对于许多简单的算术运算,定点和整数运算基本相同。但是,有些操作必须用更高的位数表示中间值然后四舍五入。例如,要将两个16位定点数相乘,结果必须在重新归一化(或饱和)回16位定点之前暂时存储在32位中。
当软件没有利用矢量化(例如基于CPU的SIMD或GPGPU)时,整数和定点算术比FPU快。当使用矢量化时,矢量化的效率更加重要,因此定点和浮点之间的性能差异没有实际意义。
某些体系结构为某些数学函数提供硬件实现,例如sin
,cos
,atan
,sqrt
,仅适用于浮点类型。某些体系结构根本不提供任何硬件实现。在这两种情况下,专用数学软件库可以通过仅使用整数或定点算术来提供这些功能。通常,这样的库将提供多级精度,例如,答案仅精确到N位精度,其小于表示的完整精度。有限精度版本可能比最高精度版本更快。
答案 2 :(得分:4)
固定点广泛用于DSP和嵌入式系统,目标处理器通常没有FPU,使用整数ALU可以合理有效地实现定点。
就性能而言,可能会根据目标架构和应用程序而有所不同。显然,如果没有FPU,那么固定点会快得多。当你有FPU时,它也取决于应用程序。例如,当在指令集中直接支持时,执行某些函数(如sqrt()或log()将会快得多,而不是通过算法实现。
我认为C或C ++中没有内置的定点类型,因为它们(或者至少是C)被设想为系统级语言,而需求定点在某种程度上是针对特定领域的,也可能是因为它是通用的处理器通常没有固定点的直接硬件支持。
在C ++中定义具有合适的运算符重载和相关数学函数的定点数据类型类可以轻松克服这种缺点。然而,这个问题有好的和坏的解决方案。可以在此处找到好的示例:http://www.drdobbs.com/cpp/207000448。该文章中代码的链接已损坏,但我将其追踪到ftp://66.77.27.238/sourcecode/ddj/2008/0804.zip
答案 3 :(得分:1)
浮点数和整数数学之间的差异取决于您的CPU。在英特尔芯片上,时钟信号的差异并不大。 Int数学仍然更快,因为有多个整数ALU可以并行工作。编译器也很聪明地使用特殊地址计算指令来优化单个指令中的加/减。转换也算作一项操作,所以只需选择你的类型并坚持使用它。
在C ++中,您可以为定点数学构建自己的类型。您只需使用一个int定义为struct并覆盖适当的重载,并使它们执行它们通常执行的操作以及将逗号放回正确位置的shift。
答案 4 :(得分:1)
在此背景下讨论“精确度”时需要小心。
对于表示中相同的位数,最大固定点值的更多有效位比任何浮点值(因为浮点格式必须给指数一些位),但最小固定点值更少比任何非非规范化浮点值(因为固定点值在前导零中浪费其大部分尾数)。
此外,根据您将固定点数除以上的方式,浮点值可能能够表示较小的数字,这意味着它具有更精确的“微小但非零”的表示形式。
等等。
答案 5 :(得分:1)
你不要在游戏中使用float,因为你使用它更快或更慢,因为在浮点中比在固定点更容易实现算法。你假设原因与计算速度有关,这不是原因,它与编程的简易性有关。
例如,您可以将屏幕/视口的宽度定义为0.0到1.0,屏幕高度为0.0到1.0。单词的深度为0.0到1.0。等等。矩阵数学等使事情真正易于实现。完成所有数学计算,直到你需要在真实屏幕尺寸上计算真实像素,例如800x400。将光线从眼睛投射到世界物体上的点并计算它穿过屏幕的位置,使用0到1的数学运算,然后将x乘以800,y乘以400并放置该像素。
浮点不单独存储指数和尾数,尾数是一个愚蠢的数字,指数和符号后面留下的数字,如23位,而不是16或32或64位。
浮点数学的核心使用定点逻辑,需要额外的逻辑和额外的步骤。根据定义比较苹果和苹果固定点数学更便宜,因为你不必在进入alu的途中操纵数据而不必在出路上操纵数据(normalize)。当您添加IEEE及其所有垃圾时,会添加更多逻辑,更多时钟周期等(正确签名的无限,安静和信令nans,如果启用了异常处理程序,则相同操作的结果不同)。正如有人在实际系统中的注释中指出的那样,您可以固定并并行浮动,您可以利用部分或全部处理器并以这种方式恢复某些时钟。浮动和固定时钟速率都可以通过使用大量的芯片空间来增加,固定将保持更便宜,但浮动可以使用这些技巧以及并行操作接近固定速度。
答案 6 :(得分:0)
未涵盖的一个问题是答案是耗电量。虽然它高度依赖于特定的硬件架构,但通常FPU比CPU中的ALU消耗更多的能量,因此如果您针对功耗很重要的移动应用,则值得考虑算法的固定点实现。
答案 7 :(得分:0)
这取决于你正在做什么。如果你使用的是固定点则会失去精确度;你必须选择小数位后的位数(这可能并不总是足够好)。在浮点时,您不必担心这一点,因为提供的精度几乎总是足以完成手头的任务 - 使用标准表单实现来表示数字。
利弊归结为速度和资源。在现代的32位和64位平台上,确实没有必要使用定点。大多数系统都带有内置FPU,这些FPU是硬连线的,可针对定点操作进行优化。此外,大多数现代CPU内在函数都带有诸如SIMD集之类的操作,这些操作通过矢量化和展开来帮助优化基于矢量的方法。所以固定点只有一个缺点。
在嵌入式系统和小型微控制器(8位和16位)上,您可能没有FPU,也没有扩展指令集。在这种情况下,您可能会被迫使用定点方法或速度不是很快的有限浮点指令集。因此,在这些情况下,定点将是更好 - 甚至是你唯一的选择。