一切数字在计算机底层都是以补码的形式存储和计算补码天然是无符号的。但为了人们方便数学计算利用计算机数据溢出绕尾的特性提出了有符号数也就是原码。补码层面的计算也是符合数学逻辑比如unsigned int 和 int计算都先转成unsigned int计算结果是unsigned int类型和你都当成有符号类型去计算结果是一样的。属于是数学统一下的一体两面。以有符号单字节为例无符号原码补码相同原码 50000 0101的补码就是 50000 0101原码-51000 0101的补码就是2511111 1011正数的补码和原码相同负数符号位不变其余取反加1就是补码。补码符号位不变其余取反加1又变成原码。负数的补码也可以通过“0加”获得0等于2560(-5) 256 - 5 251模型如下图在C语言的公式计算中可以先不考虑有符号无符号单纯以数学逻辑去计算最后看结果中间只要注意算出的数会不会因为整型提升丢失符号位即可。https://kdocs.cn/l/cgXXFjtyTtfa补充0-(-5) 256 - 251 5可以通过“0减”的方式算一个负数的绝对值。模运算补充数学语境中的除运算/和模运算%是除法带余数和取整规则上和Python中的运算是一样的但是Python有//用于取整除。C语言中只有除运算/和模运算%是取整除和求余数。被除数 商 × 除数 余数记为a q × b ra / b q 余 r。商的符号由a和b决定同号为正异号为负。Python算法上余数符号和除数M一致。C语言算法上余数符号和被除数N一致。两者运算规则上的核心差异python的商向下取整C语言的商向0取整。例子Python-10 / 3 -4 余 2-10 3 * -4 2因为-10 / 3等于-3.几向下取整到-4。C-10 / 3 -3 余 -1-10 3 * -3 -1商向0取整到-3。Python10 / -3 -4 余 -210 -3 * -4 -2C10 / -3 -3 余 110 -3 * -3 1Python-10 / -3 3 余 -1-10 -3 * 3 -1因为-10 / -3等于3.几向下取整到3。C-10 / -3 3 余 -1-10 -3 * 3 -1因为-10 / -3等于3.几向0取整到3。Python10 / 3 3 余 110 3 * 3 1C10 / 3 3 余 110 3 * 3 1Python-3 / 1000 -1 余 997-3 1000 * -1 997因为-3 / 1000等于-0.几向下取整到-1。C-3 / 1000 0 余 -3-3 1000 * 0 -3商向0取整到0。Python中商为正数时和C语言中是一样的但是商小于等于0就不一样故在C语言中当M是正值N是负值的时候一定要用公式(N % M M) % M此时的结果和Python是一致的。模运算的本质就是把N拉到[-M1, M-1]的范围内。且余数符号和除数一致当M为正数则余数范围[0, M-1]。补充数据在[0, M-1]的范围变化总共有M个数据。从S点写LEN个数据到E点E点是干净未处理的。有两个点S和E从S加LEN到E计算E本质算法是E (S LEN) M ? ((S LEN) - M) : (S LEN);对应取模算法E (S LEN) % M(S LEN)是正值直接%就行。有两个点S和E从S减LEN到E计算E本质算法是E (S - LEN) 0 ? ((S - LEN) M) : (S - LEN);对应取模算法E (S - LEN M) % M(S - LEN M)是正值直接%就行。有两个点S和E从S加LEN到E计算LEN本质算法是LEN (E - S) 0 ? (E - S) : ((E - S) M);对应取模算法LEN ((E - S) % M M) % M(E - S)可能是负值直接%的商也是负值所以套用公式。上述是数组类LEN 3是包含索引0在内。如果是定时器节拍类举例实时时间R之前时间C超时时间D。LEN 3是包含索引3在内如下图。但两者本质上是一样的只不过物理内容所在一个偏左一个偏右。补充上述“数据在[0, M-1]”的例子中M是正数“S - LEN”或“E - S”的绝对值不大于M“E (S LEN) % M”简化成“E (S LEN) % M”“E (S - LEN M) % M”简化成“E (S - LEN M) % M”算“上N条”用法“LEN ((E - S) % M M) % M”简化成“LEN (E - S M) % M”https://www.kdocs.cn/l/cp1DT0sq6ltW见20240709如果M是特殊的2的幂次数整型变量的最大值1计算时则无需求余数变量具有1个天然的模或者回绕点。