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 бит.

Другие вопросы по тегам