Разные значения пи?

ini_set('precision', 64);    
echo M_PI."<br>";
echo pi()."<br>";
echo "3.14159265358979323846264338327950<br>";

Для справки я использовал http://www.eveandersson.com/pi/digits/100

Если вы сравните результат, вы получите следующее:

3.1415926535898
3.141592653589793115997963468544185161590576171875
3.14159265358979323846264338327950

Так что же со значением точности pi()? Кажется, это совсем не так. Да, я знаю, что число Пи иррационально, но хотя бы до 100 значащих цифр оно должно быть точным?

Может ли кто-нибудь подтвердить эту проблему, и можно ли объяснить, почему после 16 цифр в php что-то не так?

echo "3.14159265358979323846264338327950<br>";-> <br> там плохо смотрится. Вы так не думаете?
WM-SH-PD-TV-FC 21.05.2018 13:11

Это из-за того, как числа с плавающей запятой хранятся в php.

NoOorZ24 21.05.2018 13:12

Почему вы используете PHP, если вам нужна точность до 100 десятичных знаков?

Tigger 21.05.2018 13:14

в 64 битах вы можете хранить int с 20 цифрами, как вы думаете, можете ли вы сохранить float с большим количеством цифр и иметь его точное?

NoOorZ24 21.05.2018 13:15

так что set_ini ('precision', 64) бессмысленно? и можно ли ввести cast float для точности с двойной плавающей запятой?

Danny F 21.05.2018 13:19

@Tigger, поэтому в любом числе число должно быть округлено ... но это не округление его полностью неверно после 16 цифр ... я хочу сказать, как я могу убедиться, что округление происходит на 16 цифрах по сравнению с получение совершенно неправильного значения в 20 цифр. Мне не нужна точность до 100 знаков после запятой, я просто подчеркивал, что это далеко, а не проблема округления.

Danny F 21.05.2018 13:25
float-point-gui.de/basic
user3783243 21.05.2018 13:32
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
8
107
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

«Проблема» в том, что значение M_PI (то же самое значение, возвращаемое pi()) жестко запрограммировано.

Из файла php_math.h:

#ifndef M_PI
#define M_PI           3.14159265358979323846  /* pi */
#endif

Изменение точности не меняет уже определенного постоянного значения. Кроме того, по-прежнему применяется обычный принцип «как хранятся числа с плавающей запятой / двойные числа».

Ответ принят как подходящий

На странице руководства расширений bcmath представлено следующее:

//bcpi function with Gauss-Legendre algorithm
//by Chao Xu (Mgccl)

function bcpi($precision){
  $n=0;
    $limit = ceil(log($precision)/log(2))-1;
    bcscale($precision+6);
    $a = 1;
    $b = bcdiv(1,bcsqrt(2));
    $t = 1/4;
    $p = 1;
    while($n < $limit){
        $x = bcdiv(bcadd($a,$b),2);
        $y = bcsqrt(bcmul($a, $b));
        $t = bcsub($t, bcmul($p,bcpow(bcsub($a,$x),2)));
        $a = $x;
        $b = $y;
        $p = bcmul(2,$p);
        ++$n;
    }
    return bcdiv(bcpow(bcadd($a, $b),2),bcmul(4,$t),$precision);
}

echo bcpi(64);
echo "<br>3.1415926535897932384626433832795028841971693993751058209749445923";

Таким образом, кажется, что ini_set ('precision', 64); не делает ничего конструктивного для обычных математических функций php (> 15), но расширение bcmath полностью игнорирует настройку.

Поэтому для работы с точностью> = 16 используйте расширение bcmath в противном случае ini_set работает до 15

И ответ @ Progman о том, что правила хранения с плавающей / двойной точностью все еще применяются - означает, что существует ограничение на 15 десятичных знаков (хотя php хранит все поплавки как двойные)

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