现在我正在做如下:
uint8_t ManualFlow = 40; // 0 -> 255 Unsigned Char
uint24_t ME; // 0 -> 16777215 Unsigned Short Long
ME = (uint24_t) ManualFlow*10; // Have to make this hack otherwise malfunction in calculation
ME /= 6;
ME *= (80 - 60);
ME /= 100;
ME *= 414;
最终结果:
40*10 = 400
400/6 = 66
66*20 = 1320
1320/100 = 13
13*414 = 5382
我喜欢的与此类似:
4/60 = 0,0667 * 20 * 4188 * 0,998 = 5576 (more accurate).
如何在不使用float
或double
的情况下更准确地执行此操作,最重要的是
不要太多地增加我的代码大小。
亲切的问候 Sonite
答案 0 :(得分:4)
您可能需要查看定点运算:
http://en.wikipedia.org/wiki/Fixed-point_arithmetic
来自WG14的18037技术报告(遗憾的是ISO / IEC TR 18037:2008的最新版本不是免费的):
答案 1 :(得分:1)
如果您确定结果永远不会溢出,请在分割之前进行所有乘法运算:
uint24_t ME;
ME = (uint24_t)ManualFlow*10;
ME *= (80 - 60);
ME *= 414;
ME /= (6 * 14);
如果您需要超过整数精度但希望避免浮点,请考虑改为使用fixed-point arithmetic。
答案 2 :(得分:1)
您指的是定点算术(与浮点相对)。您总是可以将整数的大小增加到类似uint64_t的值并乘以10以上以获得所需的精度。
但是,我建议使用base-2固定点(即向左移动一定数量的位而不是乘以10到某个功率)。 (更快)它可以更准确。
答案 3 :(得分:0)
将所有输入相乘,例如(1 <&lt; 8)进入更大的数据类型,然后执行所需的数学运算,然后将答案除以(1 <&lt; 8)。
答案 4 :(得分:0)
结论:
我的初始代码没有那么好的准确性而且“很大”。
通过这样做,我用“38字节”增加了代码并获得了更好的准确性
ME = (uint24_t) ManualFlow*100;
ME /= 6;
ME *= (Port[2].AD - Port[3].AD);
ME /= 100;
ME *= 414;
ME /= 10;
我通过固定点获得的最佳准确度,但它将代码增加到“1148字节 - &gt;
// Utility macros for dealing with 16:16 fixed-point numbers
#define I2X(v) ((int32_t) ((v) * 65536.0 + 0.5)) // Int to Fix32
#define X2I(v) ((int16_t) ((v) + 0x8000 >> 16)) // Fix to Int
ME = I2X(ManualFlow*10); //400 * 65536.0 + 0.5 = 26214400
ME = I2X(ME/6); // 26214400 / 6 = 4369066
ME = I2X(ME * 20); // = 87381320
ME = I2X(ME / 100); // = 873813
ME = I2X(ME * 414); // 361758582
ME = X2I(ME); // 158FFF76 + 8000 >> 16 15907F76 >> 16 = 5520
希望它可以帮助其他人!
亲切的问候 Sonite
答案 5 :(得分:0)
对于原版海报,我可能有点迟,但对于后人,还应该注意的是,当速度对于小型处理器来说非常关键时,通常也可以避免定点分割。通过变量进行划分通常是不可避免的,但是人们可以(几乎)总是使用乘法和移位来代替除以常数,这会占用许多处理器周期,特别是对于大于小处理器数据宽度的类型。而不是
uint16_t x = somevalue; //somevalue known to be between 0 and 65535
x /= 107;
您可以使用:
uint32_t x = somevalue;
x *= 39199; //chosen to be 2^n/107
//n chosen to maximum value without exceeding 65536
x >>= 22; //n = 22 in this case
注意:这是不太可读的代码,但如果这是一个性能至关重要的算法,则可以使用(谨慎)此优化。