在C++中,将任何浮点值(float)转换为fixed point(int,16:16或24:8)的通用方法是什么?将浮点转换为定点
编辑:为了澄清,定点值有两个部分:整数部分和小数部分。整数部分可以用有符号或无符号整数数据类型表示。小数部分由无符号数据整数数据类型表示。
为了清楚起见,我们用钱比喻一下。小数部分可能代表美分 - 美元的一小部分。 “美分”数据类型的范围应该是0到99.如果一个8位无符号整数用于定点数学,那么小数部分将被分成256个均匀可分的部分。
我希望能够解决问题。
在C++中,将任何浮点值(float)转换为fixed point(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
};
编辑:下面是基于anothercommon的方式来处理定点数(和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)
这对于将浮点数转换为整数很合适,但OP也希望得到fixed point。我不知道(C++不是我可以轻易想到的东西)。在C++中,如何做到这一点,我不知道(C++并不是我能想到的东西)。也许可以尝试缩放整数方法,即使用32位或64位整数,并以编程方式将最后的6位数字分配给小数点右侧的内容。
从浮点数转换为整数会丢弃小数部分,所以如果你想保留这个小数部分作为固定点,那么你只需在浮点数之前乘以浮点数就可以了。下面的代码不会检查你的溢出。
如果你想要16:16
double f = 1.2345;
int n;
n=(int)(f*65536);
如果你想24:8
double f = 1.2345;
int n;
n=(int)(f*256);
没有任何内置在支持C++的点数。你最好的选择是编写一个包装器'FixedInt',它需要双打并转换它们。
至于通用的方法转换... 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);
}
}
虽然这很可能包含bug仍然
****编辑**:我的第一个意见适用于凯文的编辑之前,但我会离开这里为后人。答案有时会在这里很快改变!
凯文的方法的问题是,与固定点你通常打包成一个保证字大小(通常32位)。分别声明这两个部分会让您感受到编译器结构打包的奇思妙想。是的,你可以强制它,但它不适用于16:16表示以外的任何其他功能。
KPexEA通过将所有内容打包成int来更接近标记 - 尽管我会使用“signed long”来试图在32位上进行显式指定。然后,您可以使用他的方法来生成定点值,并且位切片会再次提取组件部分。他的建议还包括24:8的情况。
(和其他人谁建议刚的static_cast .....你在想什么;?))
我给这个问题的答案写的最好的答案的家伙,但我真的使用的相关问题代码那点here。
它使用了模板,并且很容易依赖于boost lib。
如果您使用Visual C++,在考虑将所有浮点重构为固定点之前,先试验`/ fp:fast`开关。这个浮点模型开关允许优化,这可以允许浮点轻松地跳动固定点的速度。绝对是一个低估的功能。 – 2015-12-30 17:24:01