定点数的乘法
Multiplication of fixed point numbers
我有一个非常基本的问题。在我的程序中,我正在做两个定点数的乘法,如下所示。我的输入是 Q1.31 格式,输出也应该是相同的格式。为了做到这一点,我将乘法结果存储在一个临时的 64 位变量中,然后进行一些操作以获得所需格式的结果。
int conversion1(float input, int Q_FORMAT)
{
return ((int)(input * ((1 << Q_FORMAT)-1)));
}
int mul(int input1, int input2, int format)
{
__int64 result;
result = (__int64)input1 * (__int64)input2;//Q2.62 format
result = result << 1;//Q1.63 format
result = result >> (format + 1);//33.31 format
return (int)result;//Q1.31 format
}
int main()
{
int Q_FORMAT = 31;
float input1 = 0.5, input2 = 0.5;
int q_input1, q_input2;
int temp_mul;
float q_muls;
q_input1 = conversion1(input1, Q_FORMAT);
q_input2 = conversion1(input2, Q_FORMAT);
q_muls = ((float)temp_mul / ((1 << (Q_FORMAT)) - 1));
printf("result of multiplication using q format = %f\n", q_muls);
return 0;
}
My question is while converting float input to integer input (and also while converting int output
to float output), i am using (1<<Q_FORMAT)-1 format. But i have seen people using (1<<Q_FORMAT)
directly in their codes. The Problem i am facing when using (1<<Q_FORMAT) is i am getting the
negative of the desired result.
比如在我的程序中,
If i use (1<<Q_FORMAT), i am getting -0.25 as the result
But, if i use (1<<Q_FORMAT)-1, i am getting 0.25 as the result which is correct.
我哪里错了?我需要了解任何其他概念吗?
在普通平台上,int
是一个 32 位整数的补码,提供 31 位(加上一个 'sign' 位)。它有点太窄,无法表示需要 32 位数字(加上 'sign' 位)的 Q1.31 数字。
在您的示例中,这表现为表达式中的有效算术溢出,1 << Q_FORMAT
。
为避免这种情况,您需要使用提供更多数字的类型(例如 long long
)或需要更少数字的定点格式(e.g. Q1.30)。您可以使用 unsigned
来修复您的示例,但结果将比 Q2.30 少 'sign'。
我有一个非常基本的问题。在我的程序中,我正在做两个定点数的乘法,如下所示。我的输入是 Q1.31 格式,输出也应该是相同的格式。为了做到这一点,我将乘法结果存储在一个临时的 64 位变量中,然后进行一些操作以获得所需格式的结果。
int conversion1(float input, int Q_FORMAT)
{
return ((int)(input * ((1 << Q_FORMAT)-1)));
}
int mul(int input1, int input2, int format)
{
__int64 result;
result = (__int64)input1 * (__int64)input2;//Q2.62 format
result = result << 1;//Q1.63 format
result = result >> (format + 1);//33.31 format
return (int)result;//Q1.31 format
}
int main()
{
int Q_FORMAT = 31;
float input1 = 0.5, input2 = 0.5;
int q_input1, q_input2;
int temp_mul;
float q_muls;
q_input1 = conversion1(input1, Q_FORMAT);
q_input2 = conversion1(input2, Q_FORMAT);
q_muls = ((float)temp_mul / ((1 << (Q_FORMAT)) - 1));
printf("result of multiplication using q format = %f\n", q_muls);
return 0;
}
My question is while converting float input to integer input (and also while converting int output
to float output), i am using (1<<Q_FORMAT)-1 format. But i have seen people using (1<<Q_FORMAT)
directly in their codes. The Problem i am facing when using (1<<Q_FORMAT) is i am getting the
negative of the desired result.
比如在我的程序中,
If i use (1<<Q_FORMAT), i am getting -0.25 as the result
But, if i use (1<<Q_FORMAT)-1, i am getting 0.25 as the result which is correct.
我哪里错了?我需要了解任何其他概念吗?
在普通平台上,int
是一个 32 位整数的补码,提供 31 位(加上一个 'sign' 位)。它有点太窄,无法表示需要 32 位数字(加上 'sign' 位)的 Q1.31 数字。
在您的示例中,这表现为表达式中的有效算术溢出,1 << Q_FORMAT
。
为避免这种情况,您需要使用提供更多数字的类型(例如 long long
)或需要更少数字的定点格式(e.g. Q1.30)。您可以使用 unsigned
来修复您的示例,但结果将比 Q2.30 少 'sign'。