2013-03-24 6 views
5

Я читал Floating-Point guide об использовании типа float в PHP. Ответ заключается в использовании расширения BC Math. Использование строк может представлять float как точный тип и предотвращать проблемы с float и integer.Лучшая практика использования PHP float

Между тем я не нашел хороших примеров на Github и на этом сайте, работающем с расширением Math BC. Что такое чистый способ заставить PHP использовать строки, как их оценивать?

Особенно наилучшим образом использовать расширение BC Math с использованием типов данных MySQL DECIMAL?

Мой пример теста с PHP 5.4.10, правильный ответ: 0,2999999999996

<?php 
bcscale(13); 

$a = '0.3'; 
$b = '0.0000000000004'; 

echo $a-$b; // 0.3 
echo '<br />'; 
echo bcsub($a, $b); // 0.2999999999996 
echo '<hr />'; 

$a = "0.3"; 
$b = "0.0000000000004"; 

echo $a-$b; // 0.3 
echo '<br />'; 
echo bcsub($a, $b); // 0.2999999999996 
echo '<hr />'; 

$a = 0.3; 
$b = 0.0000000000004; 

echo $a-$b; // 0.3 
echo '<br />'; 
echo bcsub($a, $b); // 0.3000000000000 
echo '<hr />'; 

$a = '0.3'; 
$b = '0.0000000000004' + 0; 

echo $a-$b; // 0.3 
echo '<br />'; 
echo bcsub($a, $b); // 0.3000000000000 
echo '<hr />'; 

$a = (string) 0.3; 
$b = (string) 0.0000000000004; 

echo $a-$b; // 0.3 
echo '<br />'; 
echo bcsub($a, $b); // 0.3000000000000 
echo '<hr />'; 

$a = strval(0.3); 
$b = strval(0.0000000000004); 

echo $a-$b; // 0.3 
echo '<br />'; 
echo bcsub($a, $b); // 0.3000000000000 
?> 
+1

um, что случилось с первым и вторым случаем? Если вы хотите узнать «лучший» вариант, одинарные кавычки «лучше, чем двойные», потому что PHP будет использовать дополнительное время для заполнения имен переменных и escape-последовательностей, если вы используете двойные кавычки. – Dave

+0

Спасибо за быстрый ответ Дэйв, используя эти одинарные кавычки, делает работу. Как я буду уверен, что у меня есть значение в правильном типе, прежде чем данные могут потеряться. Например, когда выборка строк из mysql – Mike

+0

@Dave, это просто неверно с любой последней версией php. Пожалуйста, прочитайте [эту статью] (http://nikic.github.com/2012/01/09/Disproving-the-Single-Quotes-Performance-Myth.html). – Maerlyn

ответ

4

Лучший способ не использовать BC Math, но начать использовать GMP. Просто посмотрите on benchmark. GMP до 30 раз быстрее, чем математика.

Я использую DECIMAL (12, 0) и DECIMAL (27,0) и php start suck apr. при 10^19 и выше. Демонстрация:

//PHP Version 5.3.10, FreeBSD 8.2-RELEASE amd64 

$a = pow(10, 18); 
var_dump($a, $a > ($a - 1), ($a - 1) > $a, ($a - 1) == $a, ($a - 1) === $a); 
// int(1000000000000000000) 
// bool(true) 
// bool(false) 
// bool(false) 
// bool(false) 

$a = pow(10, 19); 
var_dump($a, $a > ($a - 1), ($a - 1) > $a, ($a - 1) == $a, ($a - 1) === $a); 

// double(1.0E+19) 
// bool(false) 
// bool(false) 
// bool(true) 
// bool(true) 

Я сделал Decimal класс, here is simple implementation. Позже вы можете реализовать один и тот же интерфейс, но с собственными математическими операциями php или с математикой BC или любым другим, что вы хотите. Yupp, будут накладные расходы на вызовы функций и создание объектов, но мы пишем код, который могут прочитать другие разработчики, не так ли?

P.S. Ребята из PHP Secure Communications имеют свою собственную реализацию - Math_BigInteger, которая покрывает всю потенциальную потребность, но слишком тяжела для моих задач.

Обновление: с PHP 5.6 GMP реализован internal operators overloading, поэтому ресурсы gmp могут использоваться как обычные номера (в основном).

Смежные вопросы