将 64 位整数四舍五入为 32 位整数
Rounding 64 bit integers to 32 bit integers
我有一个函数可以进行舍入操作,如下所示。它以 64 位整数作为输入,并给出 32 位整数作为输出。转换时,将 0x40000000 的因子添加到输入中。背后的原因是什么?
int rounder(long long int in)
{
INT64 out;
if ((in >> 32) == 0x7FFFFFFF)
out = in;
else
out = (INT64)0x40000000 + in;
out = out >> 31;
return (INT32)out;
}
输入似乎是一个带有 31 个小数位的 64 位定点数。如果小数部分 >= 0.5,则添加 0x40000000 值以向上舍入数字。 if
用于在四舍五入时避免可能的溢出。
让我们从一些较小的数字开始,因为它们更容易!
使用常规舍入,x.49999...或更小应向下舍入为 x,x.50000...或更多应向上舍入为 (x+1)。
(有lots种不同的舍入方法,但这是学校里学得最多的一种。)
无论何时进行整数除法(或将浮点值转换为整数),您只需丢弃小数部分。因此:
6/2 == 3.0 --> 3
5/2 == 2.5 --> 2
一个巧妙的 'trick' 是在除法之前加上除数的一半(在本例中为 1)。就像变魔术一样,您得到了正确的四舍五入!例如:
6/2 becomes (6+1)/2 == 7/2 == 3.5 --> 3
5/2 becomes (5+1)/2 == 6/2 == 3.0 --> 3
你可以通过这种方式了解它为什么有效:
5/2 becomes (5+1)/2 == 5/2 + 1/2
13/6 becomes (13+3)/6 == 13/6 + 3/6 == 13/6 + 1/2
您将真实答案加了一半。小于 x.5 的任何值仍将小于 x+1,因此仍会向下舍入,任何 x.5 或更大的值将变为 x+1 或更大,因此会向上舍入。
现在回答你的实际问题:
这个想法适用于所有除数;您向下移动 31,这与除以 2^31 相同。所以 'half-the-divisor' 是 2^30,或 0x40000000。
注意:正如其他人所指出的,此 'trick' 仅适用于正数(如果是负数则需要减去,但这是一堆蠕虫)。
这个话题有很多要考虑的;头脑清醒并不容易。一如既往,为自己尝试一些简单的例子,看看会发生什么。
我有一个函数可以进行舍入操作,如下所示。它以 64 位整数作为输入,并给出 32 位整数作为输出。转换时,将 0x40000000 的因子添加到输入中。背后的原因是什么?
int rounder(long long int in)
{
INT64 out;
if ((in >> 32) == 0x7FFFFFFF)
out = in;
else
out = (INT64)0x40000000 + in;
out = out >> 31;
return (INT32)out;
}
输入似乎是一个带有 31 个小数位的 64 位定点数。如果小数部分 >= 0.5,则添加 0x40000000 值以向上舍入数字。 if
用于在四舍五入时避免可能的溢出。
让我们从一些较小的数字开始,因为它们更容易!
使用常规舍入,x.49999...或更小应向下舍入为 x,x.50000...或更多应向上舍入为 (x+1)。
(有lots种不同的舍入方法,但这是学校里学得最多的一种。)
无论何时进行整数除法(或将浮点值转换为整数),您只需丢弃小数部分。因此:
6/2 == 3.0 --> 3
5/2 == 2.5 --> 2
一个巧妙的 'trick' 是在除法之前加上除数的一半(在本例中为 1)。就像变魔术一样,您得到了正确的四舍五入!例如:
6/2 becomes (6+1)/2 == 7/2 == 3.5 --> 3
5/2 becomes (5+1)/2 == 6/2 == 3.0 --> 3
你可以通过这种方式了解它为什么有效:
5/2 becomes (5+1)/2 == 5/2 + 1/2
13/6 becomes (13+3)/6 == 13/6 + 3/6 == 13/6 + 1/2
您将真实答案加了一半。小于 x.5 的任何值仍将小于 x+1,因此仍会向下舍入,任何 x.5 或更大的值将变为 x+1 或更大,因此会向上舍入。
现在回答你的实际问题: 这个想法适用于所有除数;您向下移动 31,这与除以 2^31 相同。所以 'half-the-divisor' 是 2^30,或 0x40000000。
注意:正如其他人所指出的,此 'trick' 仅适用于正数(如果是负数则需要减去,但这是一堆蠕虫)。
这个话题有很多要考虑的;头脑清醒并不容易。一如既往,为自己尝试一些简单的例子,看看会发生什么。