我在C语言中有一个数组,我想以类似于循环缓冲区的方式来访问它,例如:a[-1]
将返回数组的最后一个元素。
为了达到这个目的,我尝试使用模算术(显然),但问题是,当涉及负数时,我得到了相当奇怪的结果:
-1 % 4 = -1
-1 % 4U = 3
到目前为止,一切都很好。
-1 % 4000 = -1
(-1+4000U) % 4000U = 3999
(-1) % 4000U = 3295
问题:按照C标准(6.5.5#6),(a/b)*b + a%b
应该等于a并向0截断,对于a=-1, b=4000
,这个值为3295,因此它本质上不是一个bug,但是,为什么标准要这样定义呢?肯定存在某些逻辑...
我该如何编写a%b
才能得到负数a
的合理结果(当abs(a)>b
时(a+b)%b
将停止工作)?
测试应用程序:
#include <stdio.h>
int main(int argc, char **argv) {
int i=0;
#define MAX_NUM 4000U
int weird = (i-1)%MAX_NUM;
printf("%i\n", weird);
printf("%i\n", (i-1+MAX_NUM))%MAX_NUM);
printf("a: %i, b: %i, a from equation: %i\n", i-1, MAX_NUM,
((i-1)/MAX_NUM)*MAX_NUM + weird);
return 0;
}