在定点计算中使用小数部分

Use fractional part in fixed point calculation

我有一个计算如下:

1472 / 48 = 30.666667
(30 * 48) = 1440
(0.666667 * 48) = 32

所以我需要的数字是1440和32,可以用第一次计算的实部和小数部分计算出来。 使用以下代码,我找到了实数部分,但小数部分是按比例计算的。

#define SHIFT_AMOUNT    16
// 2 bytes is used to map divisions
#define SCALE_FACTOR    65535 // (2^16)
#define SHIFT_MASK      ((1 << SHIFT_AMOUNT) - 1)

uint32_t total_msgs = DATA_LENGTH << SHIFT_AMOUNT;
total_msgs /= PAYLOAD_SIZE;

uint8_t real_part = total_msgs >> SHIFT_AMOUNT; // 30
uint32_t decimal_part = total_msgs & SHIFT_MASK; // 43690

现在进行最后一次计算,我卡住了。我如何从 43690 中得到 32(实际上是 ((43690 / 65535) = 0.666667)?

解决这个问题的常用方法是%运算符:

quotient = DATA_LENGTH / PAYLOAD_SIZE;
fraction = DATA_LENGTH % PAYLOAD_SIZE;

正如其他人所提到的,由于您需要的值是商的整数部分和除法的余数,因此您可以分别使用 /% 运算符来执行此操作:

int quot = 1472 / 48;
int rem = 1472 % 48;

但是,您可以使用 div 函数,而不是对同一对数字执行两个单独的操作:

div_t result = div(1472, 48);
printf("quotient=%d, remainder=%d\n", result.quot, result.rem);

如果您经常执行此特定计算,这可能会提高您的速度,因为某些处理器(尤其是 x86)通过一条指令为您提供两个值,因此它可能会减少除法运算的数量一半。