Задать вопрос
SonkoDmitry
@SonkoDmitry
Веб разработчик

PHP и работа с числами высокой точности?

Столкнулся с проблемой, есть два вещественных числа, с точностью до восьмого-десятого знака. Например:
$a=1234567890.12345678;
$b=9876543210.87654321;


В результате сложения, должно получится число 11 111 111 100,99999999, однако имеем неприятную картину. Стандартный вариант $a+$b возвращает 11 111 111 101. Это еще пол беды, решил использовать «специализированные» функции для работы с числами высокой точности, а именно BCMath. Картина ничуть не лучше. До четвертого знака все считается отлично, а вот выше четвертого начинает округлять. Выставлен bcscale(10); Подскажите пожалуйста, как быть и что делать?
  • Вопрос задан
  • 10069 просмотров
Подписаться 3 Оценить 2 комментария
Пригласить эксперта
Ответы на вопрос 6
frostosx
@frostosx
Не пробовали через модуль больших чисел GMP? Когда-то с ним игрался — RSA пишется влегкую

www.php.net/manual/ru/book.gmp.php
Ответ написан
sirko_el
@sirko_el
Float числа в php достаточно неточные, это описанно тут:
Additionally, rational numbers that are exactly representable as floating point numbers in base 10, like 0.1 or 0.7, do not have an exact representation as floating point numbers in base 2, which is used internally, no matter the size of the mantissa. Hence, they cannot be converted into their internal binary counterparts without a small loss of precision. This can lead to confusing results: for example, floor((0.1+0.7)*10) will usually return 7 instead of the expected 8, since the internal representation will be something like 7.9999999999999991118.... So never trust floating number results to the last digit, and do not compare floating point numbers directly for equality. If higher precision is necessary, the arbitrary precision math functions and gmp functions are available.

Из линого опыта я бы посоветовал GMP функции.
Ответ написан
frostosx
@frostosx
Если используется только сложение и вычитание, то, как вариант, можно самому костыли написать:
— разбиваем число на целую и дробную часть и работаем с ними отдельно. Потом снова «склеиваем»
— или в GMP умножаем на 10^n, проводим операции, затем обратно делим на 10^n, где n — нужная точность
Ответ написан
Cyapa
@Cyapa
Обычно такие задачи решаются «длинной математикой». Как элементарный пример — можно реализовать свои функции сложения «столбиком». Скорости должно вполне хватить. Если будут затруднения, можно продумать более математически выгодные алгоритмы.
Ответ написан
я еще в школе делал такие примеры на бейсике примерно так:
1. делаем класс Float
2. сохраняем двумя int целую и дробную части
3. пишем основные математические функции с этим классом. пользуемся этими функциями

правда в школе, у нас были числа размером больше чем инт, и мы хранили их в массивах.
а в универе делали классы для хранения дробей или таких чисел. правда там был С++, и мы делали переопределение операторов, но сути эт не меняет
Ответ написан
SonkoDmitry
@SonkoDmitry Автор вопроса
Веб разработчик
удалено
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
22 дек. 2024, в 20:40
10000 руб./за проект
22 дек. 2024, в 20:34
3000 руб./за проект
22 дек. 2024, в 20:12
10000 руб./за проект