У меня возникла проблема при попытке сделать некоторые вычисления в Woocommerce, и похоже, что я получаю ошибку точности с плавающей точкой. Т.е. моя конечная сумма 448,99, но на самом деле мне нужна моя сумма 449,00.
Давайте посмотрим, как я приду к этому расчету:
Сначала я сохраняю цены моих текущих выбранных вариантов в массиве.
$regular_price_array[$variation_key] = (float)get_post_meta($selected_variation_ids[$variation_key]['variation_id'], '_regular_price', true);
Результат:
array(6) { [64]=> float(74) [65]=> float(99) [66]=> float(89) [67]=> float(89) [68]=> float(59) [69]=> float(149) }
Затем я сохраняю свои скидки в массиве:
$variation_discount_array[$discount_key] = (float)$selected_variation_ids[$discount_key]['discount'];
Результат:
array(6) { [0]=> float(19.66) [1]=> float(19.68) [2]=> float(19.68) [3]=> float(19.68) [4]=> float(19.68) [5]=> float(19.68) }
Затем я пытаюсь выполнить базовый расчет ЦЕНЫ * (1 — СКИДКА / 100), затем сложить каждую из этих цен. Вот где проблема возникает из-за точности с плавающей точкой в PHP, я думаю.
$discount_variation_price[$innerKey] = $reg_prices * number_format((1 - $discount/100),4);
Результат:
array(6) { [64]=> float(59.4368) [65]=> float(79.5168) [66]=> float(71.4848) [67]=> float(71.4848) [68]=> float(47.3888) [69]=> float(119.6768) }
Если бы вы делали математику самостоятельно только на первом, вы бы увидели проблему. В итоге вы получите ~ 59,45 (что компенсирует этот последний цент), но, конечно, это не сработает.
Я пытался использовать bcmath()
но при моей установке я получаю сообщение об ошибке, что эта функция не определена и не может найти много информации о ней, поэтому я предполагаю, что редко использовать эту функцию на веб-сайте WordPress.
Несмотря на все сказанное, я не совсем разбираюсь в этом конкретном вопросе, поэтому мне интересно, каков мой лучший способ получить ту сумму, которая мне нужна? Я совершенно в тупик! Спасибо!
Примечание: (float) здесь приведено к типу, но если раньше я не использовал тип cast, только скидка будет float, а цена будет строкой. Ошибка все еще осталась, и я подумал, что, возможно, изменение обоих типов на float поможет. Это не имело никакого влияния.
Задача ещё не решена.
Других решений пока нет …