NO_*_*AME 1 c++ floating-point unspecified-behavior
std::frexp是一个从浮点变量中删除指数并将其放入exp类型变量中的函数int。int无论指数真正需要多少位,它都会根据链接页面使用:
如果要存储的值
*exp超出 的范围int,则行为未指定。
那么,如何检查“是否超出”*exp的范围呢?int
我正在考虑static_assert在我的代码中添加 a 来比较FLT_MIN_EXP&FLT_MAX_EXP与INT_MIN&INT_MAX。但是,我担心会犯一个相差一的错误,因为我不完全理解这些常量的描述。
FLT_MIN_EXP:
最小负整数,使得 FLT_RADIX 乘以比该整数小一倍的幂是归一化的
float...
FLT_MAX_EXP:
最大正整数,使得 FLT_RADIX 乘以该整数减一的幂是可表示的有限
float...
(我已经static_assert(FLT_RADIX == 2);在代码中包含了,所以在我的例子中基数等于 10 不是问题。)
断言1:此操作通常运行良好,您无需担心任何事情。
断言 2:为了安心,如果每个系统都无法正常工作,我们希望了解它。当我们找到其中一个系统时,我们将重新审视解决方案。
断言3:如果操作是可逆的,则返回的最大和最小指数std::frexp可以用系统的类型表示。int
你std::frexp通过它的补码来反转std::ldexp。
请注意,如果int无法保存浮点的指数,则结果不是未定义的(它只是未指定),因此我们可以依赖于格式良好的测试。
TEST_CASE("The largest exponent returned by std::frexp can be represented by int") {
long double largest_ld = std::numeric_limits<long double>::max();
int exponent;
long double fraction = std::frexp(largest_ld, &exponent);
errno = 0;
REQUIRE(std::ldexp(fraction, exponent) == largest_ld);
REQUIRE(errno == 0); // just in case?
}
TEST_CASE("The smallest exponent returned by std::frexp can be represented by int") {
long double smallest_ld = std::numeric_limits<long double>::min();
int exponent;
long double fraction = std::frexp(smallest_ld, &exponent);
errno = 0;
REQUIRE(std::ldexp(fraction, exponent) == smallest_ld);
REQUIRE(errno == 0); // just in case?
}
Run Code Online (Sandbox Code Playgroud)
可能吧,但我无法理解您遇到问题的语言的同一部分,因此我正在通过编译时间检查来优化开发人员的速度。
作为一阶近似,我可以建议:
static_assert(sizeof(int) >= 32);
static_assert(std::numeric_limits<long double>::is_eec559);
Run Code Online (Sandbox Code Playgroud)
当然,当您到达一个不正确的平台时,请重新访问。
| 归档时间: |
|
| 查看次数: |
128 次 |
| 最近记录: |