Разница между результатами Python и C

1

Я написал очень простую программу в C (вычисление PI), и я получил результат следующим образом: 3.1406174152499528235728265546100601568468846380710601806640625

Результат не выглядит как правильный PI, тогда я нашел код в Python в Интернете. Я запустил его и получил что-то вроде этого: 3.1415926535897932384626433832795028841971693993751058209749 - Правильный PI.

Затем я реализовал алгоритм Python в C точно так же, и я получил такой результат: 3.1406174152499528235728265546100601568468846380710601806640625

Почему результаты Python и C из одного и того же алгоритма настолько различны и как исправить код C, чтобы получить правильный результат?

Код Python:

from decimal import*

precision = 100

getcontext().prec = 100

a = 1
b = Decimal(1) / Decimal(2).sqrt()
t = Decimal(1) / Decimal(4)
p = 1
pi = 0
for x in range(0, precision):
    nextA = (a + b) / 2
    nextB = (a * b).sqrt()
    nextT = t - p * ((a - nextA) ** 2)
    nextP = 2 * p
    pi = ((a + b) ** 2) / (4 * t)
    a,b,t,p = nextA,nextB,nextT,nextP
print pi

C код:

long double a = 1;
long double b = 1/sqrt(2);
long double t = 0.25;
long double p = 1;
long double an, bn, tn, pn, myPI;
long int x;
for(x = 0; x < 100; x++)
{
    an = (a + b) / 2;
    bn = sqrt(a * b);
    tn = t - p * ((a - an) * (a - an));
    pn = 2 * p;
    myPI = ((a + b) * (a + b)) / (4 * t);
    a = an; b = bn; t = tn; p = tn;
 }

printf("%.61Lf\n", myPI);
return 0;
  • 3
    У вас нет 100 точности в C (без внешней библиотеки, такой как GMP). long double - это точность около 80 двоичных цифр.
  • 0
    На самом деле, ни один из них не является «правильным» ИП; PI не является рациональным числом и поэтому не может быть выражено как конечная дробь, независимо от основания.
Показать ещё 1 комментарий
Теги:

3 ответа

8

Проблема заключается в опечатке в вашем коде, p = tn; должно быть p = pn; ,

Примечание: для длинных удвоений используйте sqrtl.

Обновление: если вы распечатываете аппроксимацию для pi после каждой итерации, после пятой итерации она не улучшается, и только первые 20 цифр верны. для большей точности вам нужны лучшие (не встроенные) типы данных.

  • 0
    Спасибо, я не заметил эту ошибку.
  • 0
    gmplib.org
6

Вы запрашиваете больше точности, чем могут предоставить переменные с плавающей запятой C. Вы должны использовать произвольную арифметику точности, а не плавучую точку с фиксированной точностью. Или, по крайней мере, используйте арифметику с фиксированной точностью с прецизионным значением, превышающим требуемую точность вычислений. Код Python устанавливает точность до 100 для достижения этого.


Ну, @yi_H также обнаружил ошибку в вашем коде, но даже если вы исправите то, что вы не получите такой же точности от вашего кода C, как и от вашего кода Python, по причинам, указанным выше.

  • 6
    давай, у него была ошибка на четвертой цифре;)
0

Причина в том, что числа с плавающей запятой (обычно 80 бит) являются наиболее точными числовыми типами данных C, которые должны предлагать готовые и для большинства вычислений в реальном мире более чем достаточно (OTOH, float, независимо от того, насколько велика, не может точно представить 0,85, например, но в стороне).

Python имеет встроенный большой целочисленный тип, который позволяет ему представлять произвольно большие целые числа (и, поддерживая эту реализацию, произвольно точные рациональные числа). Используя их, можно вычислить приближения PI, которые гораздо точнее, чем что-либо, что может содержать float.

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню