模数和无符号整数

4
我发现以下行为令人惊讶:
int a = -2;
int b = 5;
uint c = 5;
std::cout << a%b << '\n';
std::cout << a%c << '\n';

Output:
-2
4

当涉及比较时,混合使用有符号和无符号是有问题的——操作符%中是否存在隐含的比较,或者其他情况正在发生?


请注意,a%b也可能是3。负数上的%运算结果为正数或负数是由实现定义的。 - Goswin von Brederlow
自C++11以来就不再是这样了。 - stafusa
@GoswinvonBrederlow 请查看 https://dev59.com/E2cs5IYBdhLWcg3wmlSk#12711070 - stafusa
那个链接没有提到天气/必须向0或向下舍入。引用的C++11部分只是说(a/b)*b + a%b等于a。至少在不同的CPU上,a / b会以不同的方式四舍五入,标准允许这样做。%然后更改以保留所提到的相等性。 - Goswin von Brederlow
当它说“对于整数操作数,/运算符产生代数商,任何小数部分都被丢弃”时,我理解它的意思是进行截断-因此,“向零舍入”。@GoswinvonBrederlow - stafusa
1个回答

6
假设uint是一个不比int更窄的无符号类型,在表达式a%c的求值中,a被转换为uint,它将具有值-2+std::numeric_limits::max()+1
对于32位uint,该数字为4294967294,模5为4。
对于16位uint,该数字为65534,模5仍为4。
参考:https://en.cppreference.com/w/c/language/conversion

好的。那么,虽然没有比较,但是“%”会触发相同的转换。您能指出一个记录这一点的地方吗? - stafusa
@stafusa:我已经添加了一个虚拟代理标准的引用。 - Bathsheba
啊,好的 - 我之前搜索了“模数”,然后错过了这个:“为了获取公共实数类型进行计算的类型,以下算术运算符的参数会进行隐式转换:二元算术运算符*、/、%、+、-” - stafusa
@stafusa:没错!请随意拼凑这些内容并回答你自己的问题。我会点赞的。 - Bathsheba

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接