使用 div 和无符号整数
Using div with unsigned integers
C++标准提供了div(int, int),但没有udiv(unsigned int, unsigned int)。
如果我天真地在此函数中使用无符号整数,我可以看到对于分子中大于 2^31 - 1 的整数,这会产生错误的结果。例如(4 位半字节):
最大的4位半字节为15,二进制为1111。作为带符号的半字节,这将表示 -1。 15 除以 2 得到 7,即 0111,但是 div-1 除以 2 得到 0: 0000。
有没有一种直接的方法可以使 div 适应无符号整数,还是我最好自己编写 udiv,或者避免使用 div 和 div 类似函数?
Edit/Note:在我的例子中,我使用的是unsigned long long int
s,所以使用lldiv并不能解决问题。
假设你有一个 n 字节的整数,你可以存入 k=2^n 个数,所以如果你有一个负数,将它的值作为无符号数简单地加上 k。
所以你可以做的是,测试数字是否为负数,将 k/q 添加到结果中。
但是您可以简单地使用除法运算符 /
当年,/
和%
的结果不是C唯一定义的,div()
就诞生了。现在 /
的商被截断为 0。
unsigned
数学没有这个问题,因此对 udiv()
.
的需求较少
现在许多编译器识别附近的 a/b
和 a%b
计算并进行了很好的优化,甚至减少了 div()
的需要。建议只执行两个计算,让编译器优化它。
[编辑]
详细信息:在 C99 之前,除法可能会截断到 0、INT_MIN
或(也许可以四舍五入到最近的 - 我会研究一下)。在任何情况下 %
都是除法后的余数。 div()
被指定只做一个:除以向 0 截断。在 C99 中,div()
和 /
执行除法,商向 0 截断。
见
What is purpose of the div() library function?
What is the behavior of integer division?
C++标准提供了div(int, int),但没有udiv(unsigned int, unsigned int)。
如果我天真地在此函数中使用无符号整数,我可以看到对于分子中大于 2^31 - 1 的整数,这会产生错误的结果。例如(4 位半字节):
最大的4位半字节为15,二进制为1111。作为带符号的半字节,这将表示 -1。 15 除以 2 得到 7,即 0111,但是 div-1 除以 2 得到 0: 0000。
有没有一种直接的方法可以使 div 适应无符号整数,还是我最好自己编写 udiv,或者避免使用 div 和 div 类似函数?
Edit/Note:在我的例子中,我使用的是unsigned long long int
s,所以使用lldiv并不能解决问题。
假设你有一个 n 字节的整数,你可以存入 k=2^n 个数,所以如果你有一个负数,将它的值作为无符号数简单地加上 k。
所以你可以做的是,测试数字是否为负数,将 k/q 添加到结果中。
但是您可以简单地使用除法运算符 /
当年,/
和%
的结果不是C唯一定义的,div()
就诞生了。现在 /
的商被截断为 0。
unsigned
数学没有这个问题,因此对 udiv()
.
现在许多编译器识别附近的 a/b
和 a%b
计算并进行了很好的优化,甚至减少了 div()
的需要。建议只执行两个计算,让编译器优化它。
[编辑]
详细信息:在 C99 之前,除法可能会截断到 0、INT_MIN
或(也许可以四舍五入到最近的 - 我会研究一下)。在任何情况下 %
都是除法后的余数。 div()
被指定只做一个:除以向 0 截断。在 C99 中,div()
和 /
执行除法,商向 0 截断。
见
What is purpose of the div() library function?
What is the behavior of integer division?