在定点计算中使用小数部分
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)通过一条指令为您提供两个值,因此它可能会减少除法运算的数量一半。
我有一个计算如下:
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)通过一条指令为您提供两个值,因此它可能会减少除法运算的数量一半。