将浮点转换为定点
Converting floating point to fixed point
在C++中,将任何浮点值(float)转换为定点(int,16:16或24:8)的通用方法是什么?
编辑:为了澄清,定点值有两部分:整数部分和小数部分。整数部分可以由有符号或无符号整数数据类型表示。小数部分由无符号数据整数数据类型表示。
为了清楚起见,让我们用金钱来比喻一下。小数部分可能代表美分——一美元的小数部分。"美分"数据类型的范围为0到99。如果一个8位无符号整数用于定点数学,那么小数部分将被拆分为256个可整除的部分。
我希望这能澄清问题。
开始:
// A signed fixed-point 16:16 class
class FixedPoint_16_16
{
short intPart;
unsigned short fracPart;
public:
FixedPoint_16_16(double d)
{
*this = d; // calls operator=
}
FixedPoint_16_16& operator=(double d)
{
intPart = static_cast<short>(d);
fracPart = static_cast<unsigned short>
(numeric_limits<unsigned short> + 1.0)*d);
return *this;
}
// Other operators can be defined here
};
EDIT:这是一个更通用的类,基于另一种处理定点数的常见方法(KPexEA指出了这一点):
template <class BaseType, size_t FracDigits>
class fixed_point
{
const static BaseType factor = 1 << FracDigits;
BaseType data;
public:
fixed_point(double d)
{
*this = d; // calls operator=
}
fixed_point& operator=(double d)
{
data = static_cast<BaseType>(d*factor);
return *this;
}
BaseType raw_data() const
{
return data;
}
// Other operators can be defined here
};
fixed_point<int, 8> fp1; // Will be signed 24:8 (if int is 32-bits)
fixed_point<unsigned int, 16> fp1; // Will be unsigned 16:16 (if int is 32-bits)
从float到integer的强制转换会丢弃小数部分,所以如果你想将小数保持在固定点附近,那么在强制转换之前只需乘以float。请注意,下面的代码不会检查溢出。
如果您想要16:16
double f = 1.2345;
int n;
n=(int)(f*65536);
如果您想要24:8
double f = 1.2345;
int n;
n=(int)(f*256);
***编辑**:我的第一条评论适用于Kevin编辑之前的,但我将把它留在这里留给后人。答案有时变化如此之快
Kevin的方法的问题是,使用固定点,您通常会打包到有保证的字大小(通常为32位)。单独声明这两个部分会让您对编译器的结构打包产生突发奇想。是的,你可以强制它,但它不适用于16:16表示以外的任何内容。
KPexEA通过将所有内容打包到int中更接近标记——尽管我会使用"signed long"来尝试在32位上显式。然后,您可以使用他的方法来生成不动点,并且位切片可以再次提取组成部分。他的建议也涵盖了24:8的情况。
(还有其他建议使用static_cast的人……你在想什么?;)
我把答案给了写最好答案的人,但我确实使用了一个指向这里的相关问题代码。
它使用了模板,并且很容易放弃对boostlib的依赖。
这对于从浮点转换为整数很好,但O.p.也需要固定点。
现在,我不知道你在C++中是如何做到这一点的(C++不是我能轻易思考的东西)。也许可以尝试一种缩放整数的方法,即使用32或64位整数,并以编程方式将最后一位,例如,6位数字分配给小数点右侧的数字。
C++中没有任何内置的对不动点数字的支持。您最好的选择是编写一个包装器"FixedInt"类,该类接受doubles并转换它们。
至于要转换的泛型方法。。。int部分很简单,只需获取值的整数部分并将其存储在高位。。。小数部分的内容大致如下:
for (int i = 1; i <= precision; i++)
{
if (decimal_part > 1.f/(float)(i + 1)
{
decimal_part -= 1.f/(float)(i + 1);
fixint_value |= (1 << precision - i);
}
}
尽管这可能仍然包含错误
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- 复制列表初始化的隐式转换的等级是多少
- 正在将指针转换为范围
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 是否可以从int转换为enum类类型
- 了解 GLM- openGL 中的相机转换
- 将无符号char*转换为std::istream*C++