У меня проблемы с расчетами PHP (я думаю, что я новичок в PHP).
Я использую
function convertToBTCFromSatoshi($value){
$BTC = ($value / 100000000 );
return (float)$BTC;
}
Если $value = 10000, правильный результат "0,0001"
Но если $value = 5000, результат будет "-5.0E-5".
Любые идеи, пожалуйста :-)
Вы действительно не должны использовать математику с плавающей запятой для точных десятичных значений. Это малоизвестная истина компьютерного программирования: когда вы имеете дело с деньгами, вам следует избегать обычной математики IEEE с плавающей запятой, как чумы.
По этой причине транзакции Биткойн хранят значения как 64-битные целые числа. Потому что хранение их в виде чисел с плавающей запятой чревато ошибками.
Например, в вашей интерактивной оболочке PHP вы можете сделать что-то вроде этого, чтобы узнать, где ваши математические вычисления начинают ломаться:
php > echo 10000.00000001 * 2;
20000.00000002
php > echo 100000.00000001 * 2;
200000.00000002
php > echo 1000000.00000001 * 2;
2000000
Я тоже использую 64-битный PHP. Если вы используете 32-битный PHP, ситуация становится довольно ужасной.
Вывод здесь заключается в том, что общая точность чисел с плавающей запятой ограничена. Чем больше ваше число, тем меньше значащих десятичных разрядов оно может иметь.
Правильный способ решить эту проблему — использовать функции PHP BC Math . Вы храните свои данные в виде строк, а BCMath позволит вам выполнять вычисления с произвольной точностью. Это не так быстро, как математика с плавающей запятой, но и не совсем медленно.
/** Convert Satoshis to a string that can be displayed to users.
* input: $value Integer or string that can be parsed as an int.
* output: string (eg: "1.00400000")
*/
function convertToBTCFromSatoshi($value){
return bcdiv( intval($value), 100000000, 8 );
}
Если вы хотите обрезать нули с конца вывода, вы можете использовать trim()
функцию:
rtrim($value, "0"); // trim zeros from the right-hand side
Вы должны использовать bcmath , потому что собственные вычисления PHP не будут соответствовать вашим потребностям.
Расчет правильный, но он становится неправильным, когда показывает вам результат.
Код :
function convertToBTCFromSatoshi($value) {
$BTC = $value / 100000000 ;
return $BTC;
}
function formatBTC($value) {
$value = sprintf('%.8f', $value);
$value = rtrim($value, '0') . ' BTC';
return $value;
}
echo formatBTC(convertToBTCFromSatoshi(5000));
Выходы:
0.00005 BTC
(Математическая формула: Значение * 10 ^ -8):
$satoshi = 5000; //Satoshi to btc
echo number_format(($satoshi)*(pow(10, -8)), 8, '.', ''); //Returns 0.00005000
(Математическая формула: Значение * 10 ^ 8):
$btc = 0.00005; //Btc to satoshi
echo ($btc)*(pow(10, 8)); //Returns 5000
pow() - Exponential expression
number_format($var, 8, '.', '') - Returns a number eight decimal places
Satoshi to BTC
преобразование будет неверным в 32-битной системе для значений больше 2^32. Рекомендуется использовать bcmath для преобразования между BTC и сатоши. Я обычно использую GMP для сумм сатоши после, так как это быстрее.Я почти уверен, что вы уже нашли ответ, но ради других. вот довольно хороший способ решить эту проблему, используя bcdiv от bcmath
(PHP 4, PHP 5, PHP 7, PHP 8) bcdiv — Разделить два числа произвольной точности Документы
$value = 5000;
$convertToBTCFromSatoshi = (function ($value): string {
return bcdiv((string)$value, '100000000', 8);
})($value);
Самый простой способ
sprintf('%.8f', $amount); // 0.00000000
Поскольку вы не выбрали ответ, могу ли я предложить функцию? Этого достаточно для обработки ваших транзакций BTC.
function btc_output($x) {
$f = sprintf('%0.08f', $x);
$f = rtrim($f,'0');
$f = rtrim($f,'.');
return $f;
}
$v = 5000/100000000;
echo btc_output($v); // 0.00005
Форд
Микко Отамаа
Стефан Хименес