我一直在读这个像Arduino微型微控制器这样的浮点数学很糟糕。因此,在尝试使用更少的花车时,我发现了一些奇怪的东西。
// Baseline
float brightness = 0.05;
int result = someInt * brightness;
// Takes about twice as long
int brightness = 20;
int result = someInt / brightness;
两者都有相同的目标,将整数减少到原始值的二十分之一。但在进行数学优化时,我不确定为什么浮点数更快。
答案 0 :(得分:3)
native AVR(arduino)没有乘法或除法函数,更不用说本机浮点处理了。当你乘以它时,它基本上只是一堆加法。使用减法计算除法更难(不能太远),找到余数 - 如果浮点数然后从余数计算分数,其本身就是加/减和减法的总和。
浮点数也很慢/很差,因为C库必须弄清楚所有的十进制处理,只有在内部使用整数。您会注意到任何使用浮点数的东西都会大大增加您的程序大小(添加浮点库)
你会发现浮点除法甚至比整数除法更慢。
不知何故,浮动库在乘法中比整数除法的所有分数更有效率
答案 1 :(得分:3)
您也可以使用乘法和移位而不是除法
int brightness = 20;
int multer = 256/20;
int result = (someInt * multer) >> 8;
更多位用于" multer"更准确的结果。
答案 2 :(得分:1)
您正在将乘数与除数进行比较。苹果和梨。
除以20
,您可以使用整数乘以floor(2^k/5)
或ceiling(2^k/5)
,然后右移k+2
位。选择不会导致溢出的最大k
。
答案 3 :(得分:0)
你可以只使用位移来划分。看看https://stackoverflow.com/a/19076173/2193968 它有一个除以10的函数:
unsigned divu10(unsigned n) {
unsigned q, r;
q = (n >> 1) + (n >> 2);
q = q + (q >> 4);
q = q + (q >> 8);
q = q + (q >> 16);
q = q >> 3;
r = n - (((q << 2) + q) << 1);
return q + (r > 9);
}
所以这应该除以20:
unsigned divu20(unsigned n) {
return divu10(n)>>1;
}
位移应该比乘法或除法指令快 - 特别是如果(如EkriirkE已经说过)“原生AVR(arduino)没有乘法或除法函数”