gpt4 book ai didi

c - 如何检查 long long 是否可以放入 double 变量

转载 作者:行者123 更新时间:2023-12-02 15:37:16 25 4
gpt4 key购买 nike

我想检查 long long 变量是否可以安全地转换为 double。 DBL_MAX 没有帮助,因为有些小于该值的整数无法用 double 表示,而一些大于 2^53 的整数仍然可以容纳。

有可靠的方法吗?编译器可以优化像下面这样的语句吗?

(long long)((double)a) == a (其中 along long)

这并不要求一个可以表示为 double 的最大整数,我要求一个通用函数来检查我是否可以精确转换任何 long long 值加倍而不会出现错误。

最佳答案

OP的方法是一个好的开始。

(long long)((double)a) == a

但是有一个问题。例如。 long long a = LLONG_MAX; ((double)a)结果是超过 LLONG_MAX 的四舍五入值。

下面的肯定不会溢出double .
(病理异常:LLONG_MIN超过-DBL_MAX)。

volatile double b = (double) a;

转换回 long long并针对 a 进行测试足以实现OP的目标。只需要投保b位于long long范围。 @gnasher729让我们假设 2 的补码和 double使用FLT_RADIX != 10 。在这种情况下,最低的long long是 2 的幂,最高的是 2 的幂减 1 并转换为 double可以通过仔细计算 long long 来精确计算限制如下。

bool check_ll(long long a) {
constant double d_longLong_min = LLONG_MIN;
constant double d_longLong_max_plus_1 = (LLONG_MAX/2 + 1)*2.0;
volatile double b = (double) a;
if (b < d_longLong_min || b >= d_longLong_max_plus_1) {
return false;
}
return (long long) b == a;
}

[编辑简化 - 更通用]

b 的测试附近LLONG_MIN仅当 long long 时才需要不使用 2 的补码

bool check_ll2(long long a) {
volatile double b = (double) a;
constant double d_longLong_max_plus_1 = (LLONG_MAX/2 + 1)*2.0;
#if LLONG_MIN == -LLONG_MAX
constant double d_longLong_min_minus_1 = (LLONG_MIN/2 - 1)*2.0;;
if (b <= d_longLong_min_minus_1 || b >= d_longLong_max_plus_1) {
return false;
}
#else
if (b >= d_longLong_max_plus_1) {
return false;
}
#endif
return (long long) b == a;
}
<小时/>

我不希望编译能够优化 (long long)((double)a) == a 。 IAC,通过使用中间体volatile double ,代码阻止了这种情况。

关于c - 如何检查 long long 是否可以放入 double 变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36699009/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com