【发布时间】:2017-04-28 18:37:42
【问题描述】:
当操作数为(un)signed 或long 时,C++ 的模% 运算符的行为很奇怪。
为什么mod(signed int, unsigned int) 和mod(signed long long int, unsigned long long int) 会产生不同的结果?如果我想要正确的一个(这里:11183)怎么办?
注意:如果我按照我的算法,我应该打电话给uint64_t mod(int64_t, uint64_t)。
// Tip: 11183 is the "correct" expected result.
( int)(-3365) % ( int)(15156) = -3365
( signed int)(-3365) % ( signed int)(15156) = -3365
(unsigned int)(-3365) % (unsigned int)(15156) = 11183
( signed int)(-3365) % (unsigned int)(15156) = 11183
(unsigned int)(-3365) % ( signed int)(15156) = 11183
( long int)(-3365) % ( long int)(15156) = -3365
( signed long int)(-3365) % ( signed long int)(15156) = -3365
(unsigned long int)(-3365) % (unsigned long int)(15156) = 2555
( signed long int)(-3365) % (unsigned long int)(15156) = 2555
(unsigned long int)(-3365) % ( signed long int)(15156) = 2555
( long long int)(-3365) % ( long long int)(15156) = -3365
( signed long long int)(-3365) % ( signed long long int)(15156) = -3365
(unsigned long long int)(-3365) % (unsigned long long int)(15156) = 2555
( signed long long int)(-3365) % (unsigned long long int)(15156) = 2555
(unsigned long long int)(-3365) % ( signed long long int)(15156) = 2555
( int_fast16_t)(-3365) % ( int_fast16_t)(15156) = -3365
( uint_fast16_t)(-3365) % ( int_fast16_t)(15156) = 2555
( int_fast16_t)(-3365) % ( uint_fast16_t)(15156) = 2555
( uint_fast16_t)(-3365) % ( uint_fast16_t)(15156) = 2555
( int_fast32_t)(-3365) % ( int_fast32_t)(15156) = -3365
( uint_fast32_t)(-3365) % ( int_fast32_t)(15156) = 2555
( int_fast32_t)(-3365) % ( uint_fast32_t)(15156) = 2555
( uint_fast32_t)(-3365) % ( uint_fast32_t)(15156) = 2555
( int_fast64_t)(-3365) % ( int_fast64_t)(15156) = -3365
( uint_fast64_t)(-3365) % ( int_fast64_t)(15156) = 2555
( int_fast64_t)(-3365) % ( uint_fast64_t)(15156) = 2555
( uint_fast64_t)(-3365) % ( uint_fast64_t)(15156) = 2555
PS:关于我的系统的更多信息:
Linux pc-gi-446 4.4.0-36-generic #55-Ubuntu SMP x86_64 x86_64 x86_64 GNU/Linux
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
【问题讨论】:
-
你为什么不调查一下
(uint64_t) -3365的值是什么?我们就叫它val;那么你还在为计算val % 15156会发生什么感到惊讶吗? -
无符号类型不代表负值。当负整数转换为无符号类型时,模运算恰好在该无符号类型的范围内产生一个非负值。然后,当您应用自己的模数时,这是在该模数之上的第二个模数。应用于原始值的模运算使用
(1 + MAX)的模数,其中MAX是该无符号类型的最大值。例如(unsigned int) -3导致-3减少到以ULONG_MAX+ 1 为模的最小正值,从而得到值ULONG_MAX - 2。
标签: c++ long-integer modulo