【发布时间】:2016-01-31 01:17:39
【问题描述】:
所以...模运算似乎不适用于全 1 的 64 位值。
这是我设置边缘情况的 C 代码:
#include <stdio.h>
int main(int argc, char *argv[]) {
long long max_ll = 0xFFFFFFFFFFFFFFFF;
long long large_ll = 0x0FFFFFFFFFFFFFFF;
long long mask_ll = 0x00000F0000000000;
printf("\n64-bit numbers:\n");
printf("0x%016llX\n", max_ll % mask_ll);
printf("0x%016llX\n", large_ll % mask_ll);
long max_l = 0xFFFFFFFF;
long large_l = 0x0FFFFFFF;
long mask_l = 0x00000F00;
printf("\n32-bit numbers:\n");
printf("0x%08lX\n", max_l % mask_l);
printf("0x%08lX\n", large_l % mask_l);
return 0;
}
输出显示如下:
64-bit numbers:
0xFFFFFFFFFFFFFFFF
0x000000FFFFFFFFFF
32-bit numbers:
0xFFFFFFFF
0x000000FF
这里发生了什么?
为什么模对所有 1 的 64 位值不起作用,但对所有 1 的 32 位值起作用?
这是英特尔 CPU 的错误吗?或者以某种方式使用C?还是别的什么?
更多信息
我在装有 Intel i5-4570S CPU 的 Windows 10 机器上。我使用了 Visual Studio 2015 中的 cl 编译器。
我还使用 Windows 计算器应用程序(版本 10.1601.49020.0)通过进入程序员模式验证了此结果。如果您尝试对 0xFFFF FFFF FFFF FFFF 进行模数运算,它只会返回自身。
指定无符号与有符号似乎没有任何区别。
请赐教:)我确实有这个操作的用例......所以它不是纯粹的学术。
【问题讨论】:
-
可在 ideone 上重现:ideone.com/GzMAxK
-
你知道
0xFFFFFFFFFFFFFFFF就是-1对吧? -
这有什么问题?
0xFFFFFFFFFFFFFFFF在long long的范围之外,所以它会环绕到-1,而带有任何东西的-1 mod 将返回-1。0x0FFFFFFFFFFFFFFF是正确的long long值 -
@Mysticial:不,
0xFFFFFFFFFFFFFFFF是18446744073709551615。十六进制常量表示值,而不是表示。0xFFFFFFFFFFFFFFFF很可能是unsigned long long类型。当转换为long long时,它会产生一个实现定义的值,可能是-1LL。
标签: c cpu intel modulo modulus