C: разница между U64 и uint64_t
Я пытаюсь изучить C после работы с Java в течение нескольких лет. Я нашел код, который хотел воспроизвести, который выглядел примерно так:
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
является.
Я очень рад, если кто-то может кратко объяснить это мне, в том числе преимущество каждого из них.
Привет, Финн
1 ответ
TL;DR - для 64-разрядного целого числа без знака точной ширины, #include <stdint.h>
и использовать uint64_t
,
Предположительно, U64
пользовательский typedef для 64-разрядного целого числа без знака
Если вы используете хотя бы C99-совместимый компилятор, он будет иметь <stdint.h>
с typedef
для 64-разрядного целого числа без знака без битов заполнения: uint64_t
, Однако может случиться так, что код нацелен на компилятор, который не имеет стандарта uint64_t
определены. В этом случае может быть какой-то заголовок конфигурации, в котором тип выбран для U64
, Возможно, вы можете grep
файлы для typedef.*U64;
long
с другой стороны, это подписанный тип. Из-за различных неопределенных и определяемых реализацией аспектов подписанной математики, вы вообще не захотите использовать подписанный тип для битовой перестановки. Еще одним осложнением является то, что в отличие от Java, C long
не имеет стандартизированной ширины; вместо long
разрешено иметь ширину всего 32 бита - и так на большинстве 32-битных платформ, и даже на 64-битных Windows. Если вам когда-нибудь понадобятся точные типы ширины, вы не будете использовать int
или же long
, Только long long
а также unsigned long long
гарантированно будет иметь ширину не менее 64 бит.