嗨,我正在尝试做一个浮点数和定点数之间的转换器,而不使用任何库函数。到目前为止,定点数是16位,10位是整数部分,6位是小数部分。我一直在谷歌搜索,发现了一个可能的解决方案。
inline fixed_point_t double_to_fixed(double input)
{
return (fixed_point_t)(input * (1 << FIXED_POINT_FRACTIONAL_BITS));
}
inline double fixed_to_double(fixed_point_t input)
{
return ((double)input / (double)(1 << FIXED_POINT_FRACTIONAL_BITS));
}
我很难理解它背后的逻辑。有人能帮我解释一下吗?在这种情况下,小数位如何被C截断到只有6位😅
3条答案
按热度按时间rmbxnbpk1#
这样如何:
样本数量= 123.4567890(基数为10)
仍然以10为基数,用“3个定点小数”表示相同的数字。
要形成该值,请乘以10^3并去掉其余小数。
123.456789 * 1000 =〉整数== 123457(或123_457,其中“_”表示“固定小数点”。)
这是以10为基数转换为固定小数的示例。
很明显,除以1000可以将其反转。(丢失的精度丢失,无法恢复。
现在,不再以10为基数进行运算,而是对以2为基数表示的浮点值(
float
或double
)执行同样的操作。就这么简单。只是程度的问题...
xxhby3vn2#
假设你想要一个使用2个小数位的定点类型。
代表的是
现在考虑浮点计算
这就是它的工作原理。
通过除以“2的NUMBER-OF-FracCTIONAL-BITS次幂”,可以将定点变量的全整数表示转换为浮点值
3qpi33ja3#
来理解它背后的逻辑。
大致如下:
fixed_point_t double_to_fixed(double input)
:将input
乘以26并转换为整数。double fixed_to_double(fixed_point_t input)
:转换为double
并除以26。找到了一个可能的解决方案。
以下是一些缺点:
input
中值小于2 - 6的位将被默默地丢弃。考虑 * 舍入 *。(fixed_point_t)
的强制转换,一些整数类型,风险 * 未定义的行为 * 如果input
远远超出(fixed_point_t)
范围。1 << FIXED_POINT_FRACTIONAL_BITS
在FIXED_POINT_FRACTIONAL_BITS > 15
启动时出现问题。请为1
使用大小合适的类型。inline
。示例:
double fixed_to_double(fixed_point_t input)
基本上是可以的。当固定点的精度(OP的情况下为6)超过double
(53)时,这是一个问题。