3 回答
TA贡献1827条经验 获得超7个赞
英特尔x86处理器内部使用80位扩展精度,而double通常为64位宽。不同的优化级别会影响来自CPU的浮点值保存到内存的频率,从而从80位精度四舍五入到64位精度。
使用-ffloat-storegcc选项可获得具有不同优化级别的相同浮点结果。
或者,使用long double通常在gcc上为80位宽的类型,以避免精度从80位舍入到64位。
man gcc 全部说明:
-ffloat-store
Do not store floating point variables in registers, and inhibit
other options that might change whether a floating point value is
taken from a register or memory.
This option prevents undesirable excess precision on machines such
as the 68000 where the floating registers (of the 68881) keep more
precision than a "double" is supposed to have. Similarly for the
x86 architecture. For most programs, the excess precision does
only good, but a few programs rely on the precise definition of
IEEE floating point. Use -ffloat-store for such programs, after
modifying them to store all pertinent intermediate computations
into variables.
TA贡献1844条经验 获得超8个赞
输出应为:4.5 4.6如果您具有无限精度,或者正在使用使用基于十进制而不是基于二进制的浮点表示的设备,那么输出就是这样。但是,事实并非如此。大多数计算机使用二进制IEEE浮点标准。
正如Maxim Yegorushkin在回答中指出的那样,部分问题是计算机内部使用的是80位浮点表示形式。不过,这只是问题的一部分。问题的基础是n.nn5形式的任何数字都没有确切的二进制浮点表示形式。这些极端情况总是不精确的数字。
如果您确实希望舍入能够可靠地舍入这些极端情况,则需要一种舍入算法来解决以下事实:n.n5,n.nn5或n.nnn5等(而不是n.5)始终是不精确。找到确定某些输入值是向上舍入还是向下舍入的特殊情况,并根据与该特殊情况的比较返回四舍五入后的值。而且,您确实需要注意,优化的编译器不会将找到的特殊情况放入扩展的精度寄存器中。
请参阅即使不精确,Excel如何如何成功舍入浮点数?对于这样的算法。
或者,您可以忍受极端情况有时会错误舍入的事实。
TA贡献1942条经验 获得超3个赞
不同的编译器具有不同的优化设置。根据IEEE 754的规定,某些较快的优化设置未维护严格的浮点规则。Visual Studio中有一个特定的设置,/fp:strict
,/fp:precise
,/fp:fast
,其中/fp:fast
违反了什么可以做标准。您可能会发现,此标志是控制此类设置中的优化的因素。您可能还会在GCC中找到类似的设置,该设置会更改行为。
如果是这种情况,则编译器之间的唯一不同之处在于,默认情况下,GCC会在更高的优化条件下寻找最快的浮点行为,而Visual Studio不会在更高的优化级别下更改浮点行为。因此,它不一定是实际的错误,而是您不知道要打开的选项的预期行为。
- 3 回答
- 0 关注
- 612 浏览
添加回答
举报