# Converting satoshis to bitcoins issue using PHP

I am having PHP calculation problems (I think - i am reasonably new to PHP).

I am using

``````function convertToBTCFromSatoshi(\$value){
\$BTC = (\$value / 100000000 );
return (float)\$BTC;
}
``````

If \$value = 10000 the result is correct of "0.0001"

Yet if \$value = 5000 the result is "-5.0E-5"

Any ideas please :-)

• why the -1 ? it was a genuine question!
– Ford
Jul 14, 2013 at 21:52
• Please note that one should never use floating point in money calculations, as it may lose accuracy. stackoverflow.com/questions/3730019/… Jul 16, 2013 at 7:11
• This question appears to be off-topic because it is about php programming. Jul 20, 2013 at 18:13

You really should not use floating point math for precision decimal values. It is a little-regarded truth of computer programming that when you're dealing with money you should avoid the usual IEEE floating-point math like the plague.

This is the reason why Bitcoin transactions store values as 64-bit integers. Because storing them as floating point numbers is error-prone.

For example, in your interactive PHP shell you can do something like this to find out where your math begins to break:

``````php > echo 10000.00000001 * 2;
20000.00000002
php > echo 100000.00000001 * 2;
200000.00000002
php > echo 1000000.00000001 * 2;
2000000
``````

I'm running 64-bit PHP, too. If you are running 32-bit PHP the situation becomes pretty dire.

The take-away here is that overall precision of floating point numbers is limited. The bigger your number, the fewer meaningful decimal places it can have.

The correct way to address this problem is to use PHP's BC Math functions. You keep your data as strings, and BCMath will let you perform arbitrary-precision computations. It isn't as fast as floating point math, but it isn't exactly slow either.

``````/** 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 );
}
``````

If you want to trim the zeros from the end of the output, you can use the `trim()` function:

``````rtrim(\$value, "0"); // trim zeros from the right-hand side
``````
• Is that really a serious risk? Are you really afraid that someone will get 1 million BTC together - to steal 1 satoshi from you? Jul 20, 2013 at 0:55
• It's also about small rounding errors, and decimal values that can't be precisely expressed in binary. And don't forget, Bitcoins are meant to be infinitely divisible. It is generally accepted that the protocol can be changed to support smaller units, if required. Jul 20, 2013 at 2:38

You should use bcmath, because PHP's native calculations won't fit your needs.

• Or GMP Jul 25, 2014 at 12:39

The calculation is correct, but it becomes wrong when it shows the result to you.

Code:

``````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));
``````

Outputs:

``````0.00005 BTC
``````
• works perfect! sent a small BTC Tip
– Ford
Jul 14, 2013 at 21:19
• The valid range for satoshis won't fit into an int on php32bit. so you need to use strings, and bcdiv, NOT native division as this answer indicates. Mar 12, 2019 at 14:29

### Satoshi to BTC

(Mathematical formula: Value * 10 ^ -8):

``````\$satoshi = 5000; //Satoshi to btc
echo number_format((\$satoshi)*(pow(10, -8)), 8, '.', ''); //Returns 0.00005000
``````

### BTC to Satoshi

(Mathematical formula: Value * 10 ^ 8):

``````\$btc = 0.00005; //Btc to satoshi
echo (\$btc)*(pow(10, 8)); //Returns 5000
``````

### Explanation

``````pow() - Exponential expression
number_format(\$var, 8, '.', '') - Returns a number eight decimal places
``````
• The standard mathematical operators in PHP are limited by the system's build - 32 or 64bit. This means your `Satoshi to BTC` conversion will be wrong on a 32bit system for values larger than 2^32. It's advised to use bcmath to convert between BTC & Satoshis. I typically use GMP on the satoshi amounts after, since it's faster. Apr 2, 2016 at 12:39

I am pretty sure you have found an answer by now, but for the sake of others. here is a pretty good way to solve that using bcmath's bcdiv

(PHP 4, PHP 5, PHP 7, PHP 8) bcdiv — Divide two arbitrary precision numbers Docs

``````\$value = 5000;
\$convertToBTCFromSatoshi = (function (\$value): string {
return bcdiv((string)\$value, '100000000', 8);
})(\$value);
``````

Easiest way

``````sprintf('%.8f', \$amount); // 0.00000000
``````
• webdev1, please use code formatting when posting code. You can click edit on your own post to see how I did it. Oct 30, 2014 at 15:34

Since you have not picked an answer, can I suggest a function? It is sufficient to handle your BTC transactions

``````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
``````