Странное поведение функции pow

При запуске следующих строк кода:

int i,a; for(i=0;i<=4;i++) { a=pow(10,i); printf("%d\t",a); } 

Я был удивлен, увидев выход, он вышел 1 10 99 1000 9999 вместо 1 10 100 1000 10000 .

Какая может быть возможная причина?

Заметка
Если вы считаете, что это неточность с плавающей запятой, что в приведенном выше для цикла, когда i = 2 , значения, хранящиеся в переменной a , 99 .

Но если вы напишете вместо этого

 a=pow(10,2); 

теперь значение а составляет 100 . Как это возможно?

Я даже не могу произнести заклинание c, но я могу сказать вам, почему.

Вы установили a как int . pow() генерирует число с плавающей запятой, которое в НЕКОТОРЫХ случаях может быть только волосами менее 100 или 10000 (как мы видим здесь).

Затем вы вводите это в целое число, которое TRUNCATES указывает на целое число. Таким образом, вы теряете эту дробную часть. К сожалению. Если вам действительно нужен целочисленный результат, раунд может быть лучшим способом выполнить эту операцию.

Будьте осторожны даже там, как и для достаточно больших мощностей, ошибка может быть достаточно большой, чтобы по-прежнему вызывать сбои, давая вам то, чего вы не ожидаете. Помните, что числа с плавающей запятой несут столько точности.

Функция pow() возвращает double . Вы назначаете его переменной a , типа int . Выполнение этого не «завершает» значение с плавающей запятой, оно усекает его. Итак, pow() возвращает что-то вроде 99.99999 … за 10 ^ 2, а затем вы просто отбрасываете часть .9999 …. Лучше сказать a = round(pow(10, i)) .

Это связано с неточностями с плавающей запятой . Хотя вы проходите в int s, они неявно преобразуются в тип с плавающей точкой, поскольку функция pow определена только для параметров с плавающей запятой.

Математически целочисленная мощность целого числа является целым числом.

В рутине хорошего качества pow() этот конкретный расчет НЕ должен производить ошибок округления. Я запустил ваш код на Eclipse / Microsoft C и получил следующий результат:

 1 10 100 1000 10000 

Этот тест НЕ указывает, использует ли Microsoft поплавки и округление, или если они обнаруживают тип ваших номеров и выбирают соответствующий метод.

Итак, я выполнил следующий код:

 #include  #include  main () { double i,a; for(i=0.0; i <= 4.0 ;i++) { a=pow(10,i); printf("%lf\t",a); } } 

И получил следующий результат:

 1.000000 10.000000 100.000000 1000.000000 10000.000000 

Никто не объяснил, как на самом деле сделать это правильно – вместо функции pow просто pow переменную, отслеживающую текущую мощность:

 int i, a, power; for (i = 0, a = 1; i <= 4; i++, a *= 10) { printf("%d\t",a); } 

Это постоянное умножение на десять гарантировано даст вам правильный ответ и вполне нормально (и намного лучше, чем pow, даже если он дает правильные результаты) для таких задач, как преобразование десятичных строк в целые числа.

Давайте будем гением компьютера.