在使用Java几年之后,我正在尝试学习C。我找到了一些我想要复制的代码,如下所示:
U64 attack_table[...]; // ~840 KiB
struct SMagic {
U64* ptr; // pointer to attack_table for each particular square
U64 mask; // to mask relevant squares of both lines (no outer squares)
U64 magic; // magic 64-bit factor
int shift; // shift right
};
SMagic mBishopTbl[64];
SMagic mRookTbl[64];
U64 bishopAttacks(U64 occ, enumSquare sq) {
U64* aptr = mBishopTbl[sq].ptr;
occ &= mBishopTbl[sq].mask;
occ *= mBishopTbl[sq].magic;
occ >>= mBishopTbl[sq].shift;
return aptr[occ];
}
U64 rookAttacks(U64 occ, enumSquare sq) {
U64* aptr = mRookTbl[sq].ptr;
occ &= mRookTbl[sq].mask;
occ *= mRookTbl[sq].magic;
occ >>= mRookTbl[sq].shift;
return aptr[occ];
}代码没有那么重要,但我已经无法使用相同的数据类型:U64,我只找到了uint64_t。现在我想知道U64、uint64_t和long的区别在哪里。
如果有人能简短地向我解释一下这个问题,包括他们各自的优势,我感到非常高兴。
你好,芬恩
发布于 2018-05-27 20:22:53
对于64位精确宽度无符号整数,请使用#include <stdint.h>并使用uint64_t.
据推测,U64是64位宽无符号整数的自定义类型流。
如果您使用的是至少一个符合C99的编译器,那么它将有一个<stdint.h>和一个64位宽的无符号整数的typedef,没有填充位:uint64_t。但是,代码的目标可能是没有定义标准uint64_t的编译器。在这种情况下,可能会有一些配置头,其中为U64选择了一个类型。也许您可以grep typedef.*U64;的文件
另一方面,long是一个签名类型。由于签名数学的各种未定义和实现定义方面,您不希望在 all 上使用有符号类型进行位旋转。另一个复杂之处在于,与Java不同,C long没有标准化的宽度;相反,允许long只有32位宽--在大多数32位平台上,甚至在64位Windows上也是如此。如果需要精确的宽度类型,就不会使用int或long。只有long long和unsigned long long保证至少64位宽。
https://stackoverflow.com/questions/50556046
复制相似问题