提问人:pmor 提问时间:8/28/2023 最后编辑:pmor 更新时间:9/11/2023 访问量:44
是否有任何硬件可以将超出范围的浮点转换为非零/最小/最大整数?
Is there any hardware which converts out of range floating-point to non-zero/min/max integer?
问:
在使用 Berkeley TestFloat 时,我注意到浮点到整数转换的测试是通过检查(特别是)特定的结果值来完成的:
// file: test_a_f32_z_i32_rx.c
// function: test_a_f32_z_i32_rx
...
if ( (trueZ != subjZ) || (trueFlags != subjFlags) ) {
if (
verCases_checkInvInts
|| (trueFlags != softfloat_flag_invalid)
|| (subjFlags != softfloat_flag_invalid)
|| ((subjZ != 0x7FFFFFFF) && (subjZ != -0x7FFFFFFF - 1)
&& (! f32_isNaN( genCases_f32_a ) || (subjZ != 0)))
) {
++verCases_errorCount;
在这里,我们看到具体的结果值:、(最大有符号整数)、(最小有符号整数)。0
0x7FFFFFFF
-0x7FFFFFFF - 1
但是,根据 C11(和更高)标准,将超出范围的浮点数转换为整数会导致 UB。由于通常会导致硬件指令的生成(例如 对于x86_64),我想知道:是否有任何硬件可以将超出范围的浮点转换为非零/最小/最大整数?(int)f
cvttss2si
额外:为什么将“超出范围的整数转换为整数”会导致 IB,但将“超出范围的浮点数转换为整数”会导致 UB?
答:
从 C11 开始,C 标准将超出范围的浮点值转换为整数视为未定义行为 (UB)。这意味着编译器不受特定行为的约束,旨在防止跨平台问题。虽然某些硬件可能会单独处理此类转换,但这并不标准化或常见。Berkeley TestFloat 框架使用特定值进行测试,测试是否符合标准,但这些值可能无法反映所有硬件行为。优先考虑可移植性,遵循 C 标准的规则,避免对硬件行为的假设。显式处理超出范围的情况或使用库函数(如 isfinite)来确保在转换之前定义明确的行为。
是否有任何硬件可以将超出范围的浮点转换为非零/最小/最大整数?
关于超出范围的内容的说明。
C 将浮点到整数的转换指定为截断浮点值的转换。
对于转换为 32 位整数,有效范围略大于 [-2,147,483,648.0 ...2,147,483,647.0]。 它是 (-2,147,483,649.0 ...2,147,483,648.0)。 请注意 versus .()
[]
转换前测试的示例代码。它利用的优势始终是 - 2 的幂 (C23),这是一个梅森数。float
INT_MIN
INT_MAX
#define FLT_INT_MIN INT_MIN
#define FLT_INT_MAX_PLUS1 ((INT_MAX/2 + 1)*2.0f)
bool float_to_int_range_test(float f) {
return isgreater(f - FLT_INT_MIN, -1) &&
isless(f, FLT_INT_MAX_PLUS1);
}
评论
0
-6
-6