История изменений
Исправление uin, (текущая версия) :
Не понял причем здесь переполнение.
Переполнение это когда ты умножаешь два положительных числа, а в результате получится -1 или 0 потому что регистра не хватит, чисто математически это недопустимо и ни в одном высокоуровневом языке не допустят такого и сишный компилятор тебя настоятельно предупредит что надо бы регистровое число расширить что бы не обосраться.
Здесь же сплошные битовые операции над 32 битами, никакие математические правила тут не действуют и соответственно никаких переполнений нет. Единственная битовая операция различающая число со знаком и без это математический сдвиг с зацеплением знака, и если вот здесь: i ^ crc >> 8
так и задумано что он может случится, то надо это писать как то явно что ли:
int qspCRC(void *ptr, int len)
{
unsigned char *data = (unsigned char *)ptr;
union {
unsigned int u;
signed int i;
} tmp, crc = { .u = 0};
for (int i = 0; i < len; i++) {
tmp.i = qspCRCTable[(crc.u & 0xFF) ^ data[i]],
crc.i = tmp.i ^ crc.i >> 8, // арифметический сдвиг из-за знаковых
crc.u ^= 0xD202EF8Du;
}
return crc.i;
}
К тому же буквально только что узнал что арифметический сдвиг
sar eax, 8
оказывается выполняется первым (только потом xor), а не как обычные битовые операции последовательно, поэтому с такой мешаниной надо быть аккуратней.Исходная версия uin, :
Не понял причем здесь переполнение.
Переполнение это когда ты умножаешь два положительных числа, а в результате получится -1 или 0 потому что регистра не хватит, чисто математически это недопустимо и ни в одном высокоуровневом языке не допустят такого и сишный компилятор тебя настоятельно предупредит что надо бы регистровое число расширить что бы не обосраться.
Здесь же сплошные битовые операции над 32 битами, никакие математические правила тут не действуют и соответственно никаких переполнений нет. Единственная битовая операция различающая число со знаком и без это математический сдвиг с зацеплением знака, и если вот здесь: i ^ crc >> 8
так и задумано что он может случится, то надо это писать как то явно что ли:
int qspCRC(void *ptr, int len)
{
unsigned char *data = (unsigned char *)ptr;
union {
unsigned int u;
signed int i;
} tmp, crc = { .u = 0};
for (int i = 0; i < len; i++) {
tmp.i = qspCRCTable[(crc.u & 0xFF) ^ data[i]],
crc.i = tmp.i ^ crc.i >> 8, // арифметический сдвиг из-за знаковых
crc.u ^= 0xD202EF8Du;
}
return crc.i;
}
К тому же буквально только что узнал что арифметический сдвиг
sar %eax, 8
оказывается выполняется первым (только потом xor), а не как обычные битовые операции последовательно, поэтому с такой мешаниной надо быть аккуратней.