我希望检查一个double值是否可以表示为一个int (对于任何一对浮点(整数类型)都是相同的)。这是一种简单的方法:
double x = ...;
int i = x; // potentially undefined behaviour
if ((double) i != x) {
// not representable
}但是,它在标记行上调用未定义的行为,并触发UBSan (有些人会抱怨)。
问题:
应要求作出澄清:
我现在所面临的情况涉及到在C中从double转换到各种整数类型(int、long、long long)。然而,我以前也遇到过类似的情况,因此我对浮点数->整数和整数->浮点数转换的答案都感兴趣。
转换失败的例子:
3.5.
1.23e100.double有52个二进制数字,而64位整数类型有63个数字.例如,在典型的64位系统上,(long) (double) ((1L << 53) + 1L).1L << 53 (相对于(1L << 53) + 1)在技术上完全可以表示为double,并且我提议的代码将接受这种转换,尽管它可能不应该是我没有想到的?。
发布于 2022-04-01 11:44:07
创建的范围限制与FP类型完全相同。
“诀窍”是在不放松精度的情况下形成限制。
让我们考虑float到int。
float到int的转换是有效的(例如,32位2的补码int)对于-2,147,483,648.9999.到2,147,483,647.9999或者接近INT_MIN -1到INT_MAX + 1。
我们可以利用integer_MAX总是2-1的幂,而integer_MIN是-(2的幂)(用于一般2的补码).
避免FP_INT_MIN_minus_1的限制,因为它可能/可能不能完全编码为FP。
// Form FP limits of "INT_MAX plus 1" and "INT_MIN"
#define FLOAT_INT_MAX_P1 ((INT_MAX/2 + 1)*2.0f)
#define FLOAT_INT_MIN ((float) INT_MIN)
if (f < FLOAT_INT_MAX_P1 && f - FLOAT_INT_MIN > -1.0f) {
// Within range.
Use modff() to detect a fraction if desired.
}更多的迂腐代码将使用!isnan(f),并考虑非2的补码编码。
https://stackoverflow.com/questions/71705857
复制相似问题