为什么int * float比int / int快?

时间:2014-05-15 00:37:35

标签: c math optimization

我一直在读这个像Arduino微型微控制器这样的浮点数学很糟糕。因此,在尝试使用更少的花车时,我发现了一些奇怪的东西。

// Baseline
float brightness = 0.05;
int result = someInt * brightness;

// Takes about twice as long
int brightness = 20;
int result = someInt / brightness;

两者都有相同的目标,将整数减少到原始值的二十分之一。但在进行数学优化时,我不确定为什么浮点数更快。

4 个答案:

答案 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)没有乘法或除法函数”