<p>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.</p>

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

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

<pre><code>php &gt; echo 10000.00000001 * 2;
20000.00000002
php &gt; echo 100000.00000001 * 2;
200000.00000002
php &gt; echo 1000000.00000001 * 2;
2000000
</code></pre>

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

<p>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.</p>

<p>The correct way to address this problem is to use PHP's <a href="http://php.net/manual/en/book.bc.php">BC Math</a> 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.</p>

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

<p>If you want to trim the zeros from the end of the output, you can use the <code>trim()</code> function:</p>

<pre><code>rtrim($value, "0"); // trim zeros from the right-hand side
</code></pre>

CC BY-SA 3.0
2013-07-20T00:55:58.090Z
Is that really a serious risk? Are you really afraid that someone will get 1 million BTC together - to steal 1 satoshi from you?
Nick ODell
CC BY-SA 3.0
2013-07-20T02:38:25.657Z
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.
slashingweapon
CC BY-SA 3.0
2013-07-19T23:28:58.200Z
2013-07-19T23:34:40.587Z
2013-07-19T23:34:40.587Z
slashingweapon
<p>You should use <a href="http://php.net/manual/en/book.bc.php" rel="nofollow">bcmath</a>, because PHP's native calculations won't fit your needs. </p>

CC BY-SA 3.0
2014-07-25T12:39:40.950Z
Or [GMP](http://php.net//manual/fr/book.gmp.php)
Jan Moritz
CC BY-SA 3.0
2013-07-15T11:26:40.247Z
2013-07-15T15:04:43.627Z
2013-07-15T15:04:43.627Z
mmc4
<p>The calculation is correct, but it becomes wrong when it shows the result to you.</p>

<p><a href="http://codepad.org/Akk7Y616" rel="nofollow">Code</a>:</p>

<pre><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));
</code></pre>

<p>Outputs:</p>

<pre><code>0.00005 BTC
</code></pre>

CC BY-SA 3.0
2013-07-14T21:19:56.353Z
works perfect! sent a small BTC Tip
Ford
CC BY-SA 4.0
2019-03-12T14:29:42.247Z
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.
karimkorun
CC BY-SA 3.0
2013-07-14T19:48:38.147Z
2013-07-14T19:54:23.793Z
2013-07-14T19:54:23.793Z
Nick ODell
<h3>Satoshi to BTC</h3>

<p>(Mathematical formula: Value * 10 ^ -8):</p>

<pre><code>$satoshi = 5000; //Satoshi to btc
echo number_format(($satoshi)*(pow(10, -8)), 8, '.', ''); //Returns 0.00005000
</code></pre>

<h3>BTC to Satoshi</h3>

<p>(Mathematical formula: Value * 10 ^ 8):</p>

<pre><code>$btc = 0.00005; //Btc to satoshi
echo ($btc)*(pow(10, 8)); //Returns 5000
</code></pre>

<h3>Explanation</h3>

<pre><code>pow() - Exponential expression
number_format($var, 8, '.', '') - Returns a number eight decimal places
</code></pre>

CC BY-SA 3.0
2016-04-02T12:39:36.460Z
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.
karimkorun
CC BY-SA 3.0
2015-02-28T18:54:26.887Z
2015-03-01T01:13:05.110Z
2015-03-01T01:13:05.110Z
Jonathan Kaizer
<p>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</p>
<blockquote>
<p>(PHP 4, PHP 5, PHP 7, PHP 8)
bcdiv — Divide two arbitrary precision numbers <a href="https://www.php.net/manual/en/function.bcdiv.php" rel="nofollow noreferrer">Docs</a></p>
</blockquote>
<pre><code>$value = 5000;
$convertToBTCFromSatoshi = (function ($value): string {
  return bcdiv((string)$value, '100000000', 8);
})($value);
</code></pre>

CC BY-SA 4.0
2022-06-17T03:57:28.697Z
2022-06-17T03:57:28.697Z
Seewhy17
<p>Easiest way</p>

<pre><code>sprintf('%.8f', $amount); // 0.00000000
</code></pre>

CC BY-SA 3.0
2014-10-30T15:34:32.447Z
webdev1, please use code formatting when posting code. You can click edit on your own post to see how I did it.
Nick ODell
CC BY-SA 3.0
2014-10-30T15:08:07.970Z
2014-10-30T15:33:55.367Z
2014-10-30T15:33:55.367Z
webdev1
<p>Since you have not picked an answer, can I suggest a function? It is sufficient to handle your BTC transactions</p>

<pre><code>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
</code></pre>

CC BY-SA 3.0
2017-12-21T19:08:14.157Z
2017-12-21T19:08:14.157Z
Isaac
<p>I am having PHP calculation problems (I think - i am reasonably new to PHP).</p>

<p>I am using </p>

<pre><code>function convertToBTCFromSatoshi($value){
    $BTC = ($value / 100000000 );
    return (float)$BTC;
}
</code></pre>

<p>If $value = 10000 the result is correct of "0.0001"</p>

<p>Yet if $value = 5000 the result is "-5.0E-5"</p>

<p>Any ideas please :-)</p>

CC BY-SA 3.0
2013-07-14T21:52:21.510Z
why the -1 ? it was a genuine question!
Ford
CC BY-SA 3.0
2013-07-16T07:11:17.953Z
Please note that one should never use floating point in money calculations, as it may lose accuracy. http://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency
Mikko Ohtamaa
CC BY-SA 3.0
2013-07-20T18:13:33.133Z
This question appears to be off-topic because it is about php programming.
Stéphane Gimenez
<php>
Converting satoshis to bitcoins issue using PHP
Ford
# Converting satoshis to bitcoins issue using PHP

(Asked by: username_0 on 2013-07-14)

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 :-)

**Tags:** php

> **Comments:**
> **username_0**: why the -1 ? it was a genuine question!  
> **username_1**: Please note that one should never use floating point in money calculations, as it may lose accuracy. http://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency  
> **username_2**: This question appears to be off-topic because it is about php programming.  

---

## 7 answers

### Answer by username_3 on 2013-07-19. Score: 8

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

> **Comments:**
> **username_4**: Is that really a serious risk? Are you really afraid that someone will get 1 million BTC together - to steal 1 satoshi from you?  
> **username_3**: 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.  

---

### Answer by username_5 on 2013-07-15. Score: 4

You should use [bcmath](http://php.net/manual/en/book.bc.php), because PHP's native calculations won't fit your needs.

> **Comments:**
> **username_6**: Or [GMP](http://php.net//manual/fr/book.gmp.php)  

---

### Answer by username_4 on 2013-07-14. Score: 1

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

> **Comments:**
> **username_0**: works perfect! sent a small BTC Tip  
> **username_7**: 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.  

---

### Answer by username_8 on 2015-02-28. Score: 0

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

> **Comments:**
> **username_7**: 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.  

---

### Answer by username_9 on 2022-06-17. Score: 0

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


---

### Answer by username_10 on 2014-10-30. Score: -1

Easiest way
sprintf('%.8f', $amount); // 0.00000000

> **Comments:**
> **username_4**: username_10, please use code formatting when posting code. You can click edit on your own post to see how I did it.  

---

### Answer by username_11 on 2017-12-21. Score: -1

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


---

