浮点-特殊的浮点除法没有太多的开销



我正在尝试用浮点数进行除法。但问题是我用两个变量来表示浮点数。Qty_int和Qty_deci。例如,2.5表示为Qty_int = 2, Qty_deci = 5。

我的问题是如何将这类数字除以2 ?即2.5/2,其中2和5在不同的变量中。除法不能太昂贵,也不能使用float数据类型。有什么办法可以做到吗?

如果Qty_deci是整数,则无法区分2.5和2.05。你需要三个变量

2.5  = (2) + (5) * 10^(-1)
2.05 = (2) + (5) * 10^(-2)
        ^     ^         ^
        |     |         |

或者两个变量的值与当前值不同。

2.5  = ( 25) * 10^(-1)
2.05 = (205) * 10^(-2)
          ^         ^
          |         |

但这没有任何帮助,除非你把10换成2。

2.5  = (0x5000) / 2*(15-2)
2.05 = (0x4199) / 2*(15-2)
             ^          ^
             |          |

那么,除法是可能的。

2.5 / 2.0
= ( (0x5000) / 2*(15-2) ) / ( (0x4000) / 2*(15-2) )
= (0x5000) * 2*(15-2) / (0x4000) / 2*(15-2)
= (0x5000) << (15-2) / (0x4000) / 2*(15-2)
= (0x2800) / 2^(15-2)
= 1.25

注意,上面的除法是一个整数除法。

从技术上讲,你甚至不需要存储第二个数字。我们有一台不支持浮点运算的机器。我们用的是不动点算术。它与上面的基本相同,除了在注释中之外,你永远不会将第二个数字存储在任何地方。

例如,如果我们有16位变量,我们为符号部分保留1位,为整数部分("B2")保留2位,

与此等价的是输入函数:

int16 qty_B2 = 2.5 * 2**(15-2);  // 2.5 B2 = 0x5000

类似的操作可以由编译器或手工完成:

int16 div_B2 = 2.0 * 2**(15-2);  // 2.0 B2 = 0x4000

除法是这样的:

int32 qty_32_B2 = qty_B2 << 16;    // 2.50 B2
int32 qty_32_B4 = qty_32_B2 >> 2;  // 2.50 B4
int16 res_B2 = qty_32_B4/div_B2;   // 1.25 B4-B2=B2

等效的输出函数是:

printf("%f", res / 2**(15-2));

注意上面的除法是整数除法

Qty_deci是字符串吗?如果不是,你将如何表现2.01?

我强烈建议您不要实现自己的自定义浮点格式。重新考虑使用本机浮点格式(不使用它的原因是什么?),或者使用实现任意精度十进制数学的库。

最新更新