我想通过微控制器上的比例因子来计算多个值,并且我不能使用浮点值。 例如,一旦我得到值170,它乘以比例因子ex。 0.00065,结果是0.1105,我只需要0.11。我的值从-500到+500。我知道这是关于固定点的事情,但我想知道如何解决它。 寻求帮助
答案 0 :(得分:1)
如果你的输入是一个整数,只有输出需要是固定点,那就相当简单。
让我们使用16.16定点。这意味着你有16位的分数和16位的整数。要将整数转换为固定点,只需向左移16位(或乘以65536)。
您的输入为170
或0xAA
。所以定点表示法是0xAA0000
。
您希望乘以0.00065,即0x002b
。
要相乘,您需要将数字相乘,然后取消其中一个刻度(两个输入都被缩放,因此结果将缩放两次),或者在乘法之前取消其中一个刻度。
0xaa0000 * 0x2b = 0x1c8e0000
0x1c8e0000 >> 16 = 0x1c8e
但请注意,这可能会因较大的输入而溢出。如果您尝试使用500,则会产生大于32位的值。
如果你的输入是一个整数,你可以保持不变。让我们这样做:
0xaa * 0x2b = 0x1c8e
答案相同,但没有转变。但是你的输入显然只能是一个整数。
无论哪种方式,0x1c8e
都是您的答案,但以65536th表示。如果你取十进制数(7310)并除以65536,你将得到0.11154 ......,这是你想要的答案的近似值。
你可以用固定点选择你喜欢的任何分数/整数分割,你甚至可以混合搭配。您只需要考虑执行任何数学运算时拆分的位置,通常适当地移动输入或输出。要处理的主要问题是为您想要执行的操作选择不会溢出或下溢的格式。
要打印出值,只需要进行一些整数操作。
让我们取值0xaa1c8e
。首先,通过移动16来取整数部分。这给出了0xaa。
现在取分数,即0x1c8e。将所需数字乘以适当的数量。让我们乘以100,得到两位小数。这给了0xb2778。将它移回16,只留下0xb。
如果你使用字符串"%d.%02d", 0xaa, 0xb
printf,你会得到“170.11”,这是正确的。
这是一个粗略而准备好的例子:
int a = (0.00065 * 65536 + 0.5); // Convert the float value to fixed point, with rounding.
int b = 170;
int m = b * a;
bool n = false;
if(m < 0) {m = -m; n=true;}
int i_part = m >> 16;
int f_part = m & 0xffff;
f_part *= 100;
f_part >>= 16;
printf("%s%d.%02d\n",n?"-":"",i_part,f_part);
答案 1 :(得分:0)
用2个整数表示你的定点,并在需要执行某些操作后使用它们。例如,0.11 = 11/100
,所以你可以有两个整数变量,分子(11
)和分母(100
),它们结合起来代表一个与你的价值相对应的有理数。