PHP BCMath не может обрабатывать экспоненциальное число, если оно передается в его функцию, PHP BCMath возвращает аргумент функции bcmath неправильно сформированный

Я работаю над несколькими маленькими десятичными знаками, такими как 0,0000687, 0,0000063241, 0,0000454. Я использовал BCMath, чтобы получить наиболее точный результат, потому что он связан с расчетом денег, и до сих пор BCMath очень помогал мне в исправлении моей предыдущей ошибки, с которой я столкнулся. Но я обнаружил, что BCMath не может хорошо работать, если экспоненциальное значение, автоматически преобразованное PHP, передается в BCMath. Ниже приведен пример кода:

 $x = 0.00002123; // let say I got this value from the other computation;
                  // this $x value will automatically turn to exponential 
                  //  value by php because it have few of leading 0 after the '.' 
 

введите здесь описание изображения

Шаблон, в котором PHP начинает преобразовывать свое действительное число в экспоненциальное число: (см. изображение ниже)

введите здесь описание изображения

Как вы можете видеть на изображении выше, шаблон PHP начинает преобразовывать действительное число в экспоненциальное число, когда начальный 0 номер 4 раза -> 0,0000xxxxx (шаблон, где PHP начинает преобразовывать в экспоненциальное).

Затем, допустим, эта переменная $x будет вычислена в одной из функций PHP BCMath:

# First, I work with float number 

$calculation1 = bcadd($x,5,12); // adding variable $x to 5 
$calculation2 = bcmul($x,4,12); // multiply variable $x to 4
$calculation3 = bcdiv($x,5,12); // divide variable $x to 5
 
# Second, I tried to work with string number

$y = (string) $x;
$calculation4 = bcadd($y,5,12);
$calculation5 = bcmul($y,4,12);
$calculation6 = bcmul($y,4,12);

Результат оказался ошибкой, вот скриншот для переменной $x:

введите здесь описание изображения

И здесь результат оказывается ошибкой, вот скриншот для переменной $y (сначала перейдите к строке, потому что BCMath хорошо работает со строкой):

введите здесь описание изображения

Важное примечание .

  • Таким образом, у BCMath возникают проблемы при работе с экспоненциальным значением, я не могу избежать этого экспоненциального значения, потому что PHP автоматически анализирует его до экспоненциального числа, когда оно достигает своего шаблона (см. изображение, которое я прикрепляю выше).
  • Учитывая, где переменная $x я получаю из разных вычислений, поэтому в реальном коде я не могу жестко закодировать ее так, как хочу.

person Bathulah Mahir    schedule 18.03.2021    source источник
comment
"шаблон PHP начинает преобразовывать вещественное число в экспоненциальное число" - здесь PHP ничего не конвертирует внутренне, это просто представление таких крошечных чисел, когда вы выводите их в текстовом виде.   -  person CBroe    schedule 18.03.2021
comment
Строковое значение не является числом, но вы пытаетесь обращаться с ним как с таковым, и в этом, похоже, настоящая проблема.   -  person CBroe    schedule 18.03.2021
comment
Настоящий вопрос здесь, как заставить его работать с bcmath, вы можете попробовать в своей среде, и вы можете скопировать точно такой же код, который я написал/скриншот выше   -  person Bathulah Mahir    schedule 18.03.2021
comment
Вы заставляете это работать, работая с реальными числами, а не со строками, содержащими вещи, которые выглядят как числа.   -  person CBroe    schedule 18.03.2021
comment
брат, я работаю как с реальным номером, так и с номером строки, вы можете внимательно посмотреть и прочитать мой скриншот и код. Я пробовал оба, а не только один   -  person Bathulah Mahir    schedule 18.03.2021
comment
да, извините за это, но я сделал снимок экрана, чтобы доказать, что ошибка действительно существует, извините, если не можете загрузить это. но это доказательство того, что ошибка действительно происходит. Я тоже попробовал реальное число экспонент, и это действительно выдает эту ошибку   -  person Bathulah Mahir    schedule 18.03.2021
comment
Поможет ли этот вопрос?   -  person El_Vanja    schedule 18.03.2021
comment
@CBroe Последний комментарий, возможно, был немного резким, поскольку сам код присутствует в вопросе вместе со скриншотами.   -  person El_Vanja    schedule 18.03.2021
comment
Ошибка о неправильно сформированном значении появляется только в PHP 7.4, 3v4l.org/veQgt Но это исправляется само собой, как только номер фактически предоставляется в виде строки, 3v4l.org/TEIaF   -  person CBroe    schedule 18.03.2021
comment
Я тоже пытался использовать обычный поплавок, он выдает эту ошибку. здесь простой вызов, сделанный в среде php bcadd (0.0000000254,4,12), вызвав этот простой вызов, php выдаст ту же ошибку, что и у меня выше, я спрашиваю здесь, чтобы попросить решение.   -  person Bathulah Mahir    schedule 18.03.2021
comment
Вы проверили другой вопрос, на который я ссылался? О преобразовании числа с плавающей запятой в строковое представление. Я считаю, что это должно решить вашу проблему.   -  person El_Vanja    schedule 18.03.2021
comment
Что ж, решение очевидно и тривиально, предоставьте число в виде строки, как сказано в руководстве: bcadd("0.0000000254",4,12); Проблема здесь заключается в том, что вы ожидаете, что это примет …E-05 в форме строки как число, но это не так.   -  person CBroe    schedule 18.03.2021
comment
да, теперь я могу жестко запрограммировать его на 0,0000000254, но когда это значение полностью вычисляется в другом месте, и моя функция просто принимает его значение как экспоненциальное представление (поскольку вычисление, рассчитанное в другом месте, возвращает в формате с плавающей запятой, и я получил его), тогда я получить эту ошибку   -  person Bathulah Mahir    schedule 18.03.2021


Ответы (1)


Функции bcmath в PHP работают с числовыми строками. Не числа с плавающей запятой и, что важно, не числа с плавающей запятой, преобразованные в строку. Это упоминается в введении к расширению:

Действительные (иначе правильно сформированные) числа BCMath — это строки, соответствующие регулярному выражению /^[+-]?[0]*[1-9]*[.]?[0-9]*$/.

Преобразование числа с плавающей запятой в строку в PHP часто дает вам результат в экспоненциальном представлении — синтаксис 2.123E-5, который вы видите в своих результатах. bcmath не может работать с этим представлением; чтобы соответствовать приведенному выше регулярному выражению, строки должны содержать аргумент в десятичной форме.

Предупреждение, которое вы видите, было добавлено в PHP 7.4 и указано в Назад Несовместимые изменения для этой версии. Ранее любые неправильно сформированные аргументы молча интерпретировались как ноль (что не совсем помогало).

Как упоминалось в комментариях, самый простой способ преобразовать число с плавающей запятой в его десятичную форму — использовать number_format, обеспечивая ту же точность, которую вы уже используете для функций bc:

$precision = 12;
$x = 0.00002123;
echo bcadd(number_format($x, $precision), 5, $precision);

5.000021230000

См. https://3v4l.org/SuWIu.

person iainn    schedule 18.03.2021