@Decker

PHP. Умножение 6-ти float, переместительный закон умножения не работает?

Интересная логическая задача. Всем известно про переместительный закон умножения, т.е. что A*B*C = A*C*B ... простой пример на PHP для вещественных чисел, показывающий что это не так:
<?php

$d4 = 6031 * 8109 * 980 * 1909 * 429 * 1714;
var_dump($d4);
var_dump(sprintf("%020.0f",$d4));

$d4 = 8109 * 980 * 1909 * 429 * 1714 * 6031;
var_dump($d4);
var_dump(sprintf("%020.0f",$d4));

?>

Получаем результат:
float(6.7275470345782E+19)
string(20) "67275470345782386688"
float(6.7275470345782E+19)
string(20) "67275470345782378496"

Т.е. в первом случае мы имеем 67275470345782386688, а во втором случае с теми же сомножителями 67275470345782378496.

Два вопроса.

1. Почему? (я так понял что ошибка накапливается на каждом этапе умножения в связи с точностью float)
2. В каком порядке PHP разбирает первое выражение? Т.е. в каком именно порядке совершаются действия в выражении 6031 * 8109 * 980 * 1909 * 429 * 1714 ? Каким образом можно повторить данный результат "по шагам"?
  • Вопрос задан
  • 539 просмотров
Решения вопроса 1
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
https://en.wikipedia.org/wiki/IEEE_754-1985

в PHP оператор умножения имеет левую ассоциативность, то есть выражение выполняется слева на право. В вашем случае - по порядку.

$d4 = ((((6031 * 8109) * 980) * 1909) * 429) * 1714;
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@Nc_Soft
НИКОГДА не проводите арифметические операции на пхп без спец библиотек
php >  echo bcmul(6031, bcmul(8109, bcmul(980, bcmul(1909, bcmul(429, 1714, 0), 0), 0), 0), 0);
67275470345782378680
php > echo bcmul(8109, bcmul(980, bcmul(1909, bcmul(429, bcmul(1714, 6031, 0), 0), 0), 0), 0);
67275470345782378680
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы