问题标签 [subnormal-numbers]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - FLT_HAS_SUBNORM 为 0:什么 fpclassify() 应返回:FP_SUBNORMAL 或 FP_ZERO,还是导致 UB?
后续问题:
- FLT_HAS_SUBNORM 为 0:执行 fpclassify() 与手动构造的次正规导致 UB 还是导致 WDB 返回 FP_SUBNORMAL?
- 如果次正规数的存在是可选的(HAS_SUBNORM),那么为什么 FP_SUBNORMAL 的存在是强制性的?
问题:在FLT_HAS_SUBNORM is 0
什么情况下fpclassify(<subnormal>)
会返回:FP_SUBNORMAL
or FP_ZERO
,or 导致UB?请详细说明。
换句话说:如果FLT_HAS_SUBNORM is 0
实现具有DAZ(非正规为零)属性?(有关详细信息,请参阅链接#1 中用户@njuffa 的评论。)如果是/否,那么该属性应应用于所有涉及 FP 编号(对象)的操作,还是应用于某些涉及 FP 编号(对象)的操作?
UPD20210825:委员会的答复:
它是 FP_ZERO。
结果:
- 如果实现
FLT_HAS_SUBNORM is 0
应将 DAZ(非正规为零)属性设置为 1?是的。 - 是否应将 DAZ=1 应用于所有涉及 FP 数(对象)的操作?进行中...
c - 如果 FLT_HAS_SUBNORM 为 -1,那么 1.0f / FLT_MAX 是否会产生次正规数或导致未定义行为(UB)?
问题:如果FLT_HAS_SUBNORM
是-1,那么会1.0f / FLT_MAX
产生次正规数吗?
ISO/IEC 9899:2011 (E):
-1 不确定25
- 如果浮点运算不能始终将次正规表示解释为零或非零,则打算将其表征为不确定。
在上面的问题中:
- 根据H.2.3.2(浮点运算)除法(divF)是浮点运算。
- 值
1.0f
和FLT_MAX
是正常数字。
注意:如果省略了行为的明确定义,那么根据 C 标准(ISO/IEC 9899:2011 (E))(强调添加):
未定义的行为在本国际标准中以“未定义的行为”一词或省略任何明确的行为定义来表示。
c - 如果 FLT_HAS_SUBNORM 为 0,那么转换 (float)1E-45 是否应返回 0x1p-149?
简单的问题:如果FLT_HAS_SUBNORM
是 0,那么转换应该(float)1E-45
返回0x1p-149
吗?
问题的原因:ISO/IEC 9899:2011 (E) 指定了FLT_HAS_SUBNORM
/ DBL_HAS_SUBNORM
only wrt floating-point operations 的行为。根据 H.2.3.2(浮点运算),浮点精度(取自 F.3 运算符和函数的术语)之间的转换不是浮点运算。因此,为FLT_HAS_SUBNORM
/指定的行为与浮点精度之间DBL_HAS_SUBNORM
的转换无关。因此,结论是转换将返回。这个结论正确吗?(float)1E-45
0x1p-149
UPD:解释这些问题的原因:目前我有一些测试来测试 FP 操作生成的结果的正确性(包括转换)。FLT_HAS_SUBNORM is 0
我在使用和 的环境下运行这些测试FLT_HAS_SUBNORM is -1
。主要问题是在编译器选项的某些组合中,某些测试失败了。例如:在FLT_HAS_SUBNORM is 0
:
- 硬件(FPU)FP:
(float)1E-45
返回0x1p-149f
- SW (libfp) FP:
(float)1E-45
返回0.0f
测试参考值:0.0f
.
因此,有必要了解是否:
- 测试有一个错误(写错了:例如,没有检查
HAS_SUBNORM
);或者 - 编译器有错误;或者
- SW (libfp) FP 有一个错误;或者
- HW (FPU) FP 有一个错误(模拟器中的错误;它也会发生);或者
- 先前案例的所有可能组合。
第一步是阅读标准(C / IEEE 754)并尝试回答开放性问题。然而,事实证明,wrt FP 的许多方面都没有明确定义。因此,处理现有失败测试的情况的最合理方法是什么?
另请注意,理想情况下,测试是以“通用方式”独立编写的(检查系统/环境的功能:检查功能宏、检查限制等),即不知道特定编译器的特定 FP 细节用于 FP 计算(或者人们称之为FP environment)。
format - IEEE 754:格式的基本原理:次正规数和正规数
有人可以澄清一下:
- 为什么次正规数的格式究竟是
±(0.F) × 2^-126
而不是±(1.F) × 2^-127
? - 为什么正常数字的格式是:
±(1.F) × 2^exp
而不是说±(11.F) × 2^exp
,或者说,±(10.F) × 2^exp
?
c - HAS_SUBNORM 为 0:FTZ(清零)应该在细度检测之前还是细度检测之后进行?
考虑1.1754944E-38f - 1.1754945E-38f
(两者都是正常的)。
如果HAS_SUBNORM is 1
,那么答案是-1E-45f
(次正常的)并且不会引发异常。
如果HAS_SUBNORM is 0
,那么答案是-0.0f
(次正常-1E-45f
被刷新为零)。问题:应Underflow and Inexact
提高?
IEEE 754-2008, 7.5 下溢:
当检测到微小的非零结果时,应发出下溢异常信号。
检测到微小:
- 四舍五入后,或
- 舍入前。
但是,应在哪一步执行 FTZ(清零)逻辑:
- 在微小检测之前,或
- 细小检测后?
问题的原因:某些硬件不支持次正规数,但在上面的示例中确实增加了。 Underflow and Inexact
这意味着此类硬件在微小检测后会执行 FTZ。我想知道这是否是正确的行为。
c - HAS_SUBNORM 为 0:“次正常结果”是在舍入前还是舍入后确定?
C11,5.2.4.2.2 浮动类型的特征 <float.h>,10,脚注 26:
如果没有浮点运算从非次正规输入产生次正规结果,即使类型格式包括次正规数的表示,也打算将其表征为不存在。
这里的“次正常结果”是在四舍五入之前还是在四舍五入之后确定的?
测试表明,有些实现是在舍入之前做的,有些实现是在舍入之后做的。
这是测试:
UPD(在完成更多研究/实验之后)。
- FTZ 逻辑的确切执行位置与这个问题无关:无论是在舍入前还是舍入后执行 FTZ 逻辑,舍入(交付)的结果都不是次正规的。
- 如果一个实现不支持次正规数,那么这种实现不符合 IEEE 754。因此,这种实现可以自由选择在哪一步执行 FTZ 逻辑。实验证实: FTZ=1(或永久 FTZ=1)配置的不同实现可能在不同的步骤执行 FTZ 逻辑,因此产生不同的结果:
±0.0
或±<TYPE_PREFIX>_MIN
. - 额外:在 FTZ=1 的情况下引发浮点异常:与 2 中的情况相同。:IEEE 754 不符合标准的实现可以自由地做他们想做的事。
database - Redshift 是否支持 IEEE 754 浮点数?
最近,我在尝试将DOUBLE PRECISION
postgres 数据库中的列中的数据加载DOUBLE PRECISION
到 AWS Redshift 中的列时遇到了溢出错误:
溢出,2.8079240261080252e-316(双重有效范围 2.225074e-308 到 1.797693e+308)
根据双精度浮点数的维基百科条目,redshift支持的数字范围似乎包括“正常双精度”,但不包括“次正常双精度”。
作为附加检查,我尝试检索最小的次正规双精度,这在 postgres 中是成功的,但在 redshift 中导致溢出错误:
基于这种观察到的行为,我们是否可以得出结论,Redshift 没有正确实现浮点数的 IEEE 754 标准?有没有人在支持和不支持次正常数字的系统之间进行互操作的相关经验?