Я столкнулся с этой необычной ошибкой, работая над некоторыми побитовыми упражнениями. Когда вывод pow()
был приведен к unsigned int
, результат pow()
, вызванный с переменной в качестве показателя степени, стал нулевым, а результат, когда показатель степени был буквальным целым числом, был принудительно обычно равно 0xFFFFFFFF (2^32 - 1). Это происходит только в том случае, если значение чрезмерно велико, в данном случае 2^32. Тип переменной, используемой в качестве аргумента экспоненты, похоже, не влияет на этот результат. Я также попытался сохранить вывод обоих вызовов pow()
как удвоение, а затем применить принуждение при ссылке на переменные; диспропорция сохранялась.
#import <math.h>
int main (void) {
int thirtytwo = 32; // double, unsigned, etc... all yielded the same result
printf("Raw Doubles Equal: %s\n", pow(2, 32) == pow(2, thirtytwo) ? "true" : "false"); // -> true
printf("Coerced to Unsigned Equal: %s\n", (unsigned) pow(2, 32) == (unsigned) pow(2, thirtytwo) ? "true": "false"); // -> false
return 0;
}
Из любопытства я пропустил тот же код через clang/llvm и получил другой результат: независимо от того, был ли показатель степени переменной, приведение результата к беззнаковому целому дало ноль (как и ожидалось).
Изменить: максимальное 32-битное целое число без знака равно 2^32 - 1
, поэтому принудительный вывод не является правильным. Моя ошибка заключалась в превышении ограничения на целочисленный размер. Почему gcc по существу округляется до максимального целочисленного значения, является интересным любопытством, но не имеет особого значения.
(unsigned) pow(2, 32) == 0xFFFFFFFF
. - person Alex Patch   schedule 28.03.20170xFFFFFFFF == 2^32 -1
, а не2^32
. И компилятор может оптимизировать, как он хочет, когда вы делаете вызов с константами, а не с переменными. Разные компиляторы могут даже делать разные вещи. - person StoryTeller - Unslander Monica   schedule 28.03.20171 << exp
- person phuclv   schedule 28.03.2017