检查float是否可以表示为整型
Check if float can be represented as integral type
如何检查float
是否可以表示为整数类型,而不需要通过强制转换调用未定义行为?这是§4.9.1所禁止的:
浮点型的右值可以转换为an型的右值整数类型。转换截断;也就是小数部分就会被丢弃。如果截断的值不能,则行为未定义以目标类型
表示
对于C来说有这个问题,但是被接受的答案显然会导致未定义的行为(首先是通过简单的强制转换,然后通过使用union hack,这使得整个事情对我来说非常可疑)。
我可以看到有一个完全兼容的解决方案是多么困难,但是一个实现定义的(假设IEEE-754浮动)也是可以接受的。
检查truncf(x) == x
。(函数在<math.h>
中)当且仅当x没有小数部分时,将比较true。然后,将x与类型的范围进行比较。
示例代码(未测试)
#include <cfenv>
#include <cmath>
#pragma STDC FENV_ACCESS on
template<class F, class N> // F is a float type, N integral.
bool is_representable(const F x)
{
const int orig_rounding = std::fegetround();
std::fesetround(FE_TOWARDZERO);
const bool to_return = std::trunc(x) == x &&
x >= std::numeric_limits<N>.min() &&
x <= std::numeric_limits<N>.max();
std::fesetround(orig_rounding);
return to_return;
}
舍入设置为0时,将整型的最小值和最大值隐式转换为浮点型时不会溢出。在包括i386在内的许多体系结构上,转换为long double
也将提供足够的精度来精确表示64位int。
您可以使用snprintf()
中的%a
格式类型说明符来访问尾数和指数,然后您可以计算出该数字是否是整数,以及它是否适合特定大小的整数类型。我在另一个问题中使用了这个方法。
考虑从1到MAX_FLOAT的正整数。对于ieee754指数表示2的幂(它以偏置存储)。ieee -754格式使用1个符号位,8个有偏指数位和23个尾数位。的尾数是这个数的阶乘部分。最高位是1/2,接下来是1/4,接下来是1/8……
1 ~ 1.999…有相同的指数。(1)
范围内有1个整数2 ~ 3.999…有相同的指数。在(2,3)范围内有2个整数。3有最高的尾数位,所以它需要前导尾数位。如果任何其他低尾数位是,那么它不是整数。因为它是2或3加上小数位的值
从4到7.999…有相同的指数。范围内有4个整数(4,5,6,7)它们使用最高的2个尾数位。如果设置了其他尾数位,则它不是整数。
8 ~ 15.999…有相同的指数。范围内有8个整数(8,9,10,11,12,13,14,15)这些使用3个最高尾数位。如果设置了其他尾数位,则它不是整数。
我希望你能看到的模式,当你增加指数,可能的整数的数量加倍。因此,忽略n个最高尾数位,并测试是否设置了最低尾数位。如果是,则该数字不是整数。
这个表显示了常数指数值0x40加上下一个最高位,并且只有整数的高阶尾数位被设置
Float Hex
4 0x40800000
5 0x40a00000
6 0x40c00000
7 0x40e00000
将浮点数转换为UInt32
float x = 7.0;
UInt32 * px = (UInt32*)&x;
UInt32 i = *px;
- C 字符串返回字符串的整数/双精度/长整型值
- 是什么导致了这种使用三进制而不是短整型的有符号int到无符号int转换
- 无法在 Arduino 中uint8_t数组转换为无符号长整型数组
- JNI 日期值转换问题,在C++中获取不同的长整型值
- 将长整型值打印为带有前导零的十六进制
- 为什么在传递长整型时调用具有两个双精度类型的参数的重载函数?
- 将整型常量映射到类型
- 将元组和整型实例合并到引用元组中
- 提升不良词法强制转换:将字符串转换为无符号长整型时,无法将源类型值解释为目标
- 为什么C++不允许两个同名的函数/类模板,区别仅在于非类型模板参数(整型)的类型?
- 将最小值整数转换为无符号长整型
- 如何将小端格式的QByteArray转换为无符号长整型
- 直接初始化无符号短整型的标准行为
- 无符号长整型和无符号 int 之间有什么区别,这 2 种类型应该如何在 c# 中封送?
- 无符号和有符号短整型的位宽
- 将整型转换为浮点型时检测溢出
- 长整型的位表示未正确打印
- 检查float是否可以表示为整型
- 在C++中,用十六进制或八进制表示的整型文字的默认类型是什么
- 如何将表示像素的字符数组读取为无符号整型