<p>There are 3 representations of the same thing (with varying degrees of precision) in Bitcoin:</p>
<ul>
<li>bits - unsigned int 32-bit</li>
<li>target - unsigned int 256-bit</li>
<li>difficulty - double-precision float (64-bit)</li>
</ul>
<p>and 6 methods are necessary to convert between any two of these:</p>
<ul>
<li>bits -&gt; target (<code>SetCompact()</code> in <code>bitcoin/src/arith_uint256.cpp</code>)</li>
<li>bits -&gt; difficulty (<code>GetDifficulty()</code> in <code>bitcoin/src/rpc/blockchain.cpp</code>)</li>
<li>target -&gt; bits (<code>GetCompact()</code> in <code>bitcoin/src/arith_uint256.cpp</code>)</li>
<li>target -&gt; difficulty (same as target -&gt; bits -&gt; difficulty)</li>
<li>difficulty -&gt; bits (not done in <code>bitcoin/src</code>)</li>
<li>difficulty -&gt; target (same as difficulty -&gt; bits -&gt; target)</li>
</ul>
<p>The Bitcoin source code can do the conversion from bits -&gt; difficulty as asked in the question, but cannot do the conversion from difficulty -&gt; bits as also asked in the question.</p>
<p>I have written my own implementation of the difficulty -&gt; bits conversion in vanilla Javascript by mimicking the target -&gt; bits conversion where possible, plus some additional checks:</p>
<pre class="lang-js prettyprint-override"><code>function difficulty2bits(difficulty) { 
    if (difficulty &lt; 0) throw 'difficulty cannot be negative';
    if (!isFinite(difficulty)) throw 'difficulty cannot be infinite';
    for (var shiftBytes = 1; true; shiftBytes++) {
        var word = (0x00ffff * Math.pow(0x100, shiftBytes)) / difficulty;
        if (word &gt;= 0xffff) break;
    }
    word &amp;= 0xffffff; // convert to int &lt; 0xffffff
    var size = 0x1d - shiftBytes;
    // the 0x00800000 bit denotes the sign, so if it is already set, divide the
    // mantissa by 0x100 and increase the size by a byte
    if (word &amp; 0x800000) {
        word &gt;&gt;= 8;
        size++;
    }
    if ((word &amp; ~0x007fffff) != 0) throw 'the \'bits\' \'word\' is out of bounds';
    if (size &gt; 0xff) throw 'the \'bits\' \'size\' is out of bounds';
    var bits = (size &lt;&lt; 24) | word;
    return bits;
}
</code></pre>
<p>It is possible to validate that the above function gives correct answers by doing the following conversion:</p>
<pre><code>bits -&gt; difficulty -&gt; bits
</code></pre>
<p>Where bits -&gt; difficulty is done using Bitcoin's <code>GetDifficulty()</code> and difficulty -&gt; bits is done using <code>difficulty2bits()</code> above. If we arrive back at the same bits value then the <code>difficulty2bits()</code> function is correct. The only exception is when <code>(bits &amp; 0x00800000) != 0</code>, since this means that bits is a negative number, whereas difficulty is always a positive number in Bitcoin.</p>
<p>I have tested the above <code>difficulty2bits()</code> function and it does return the same result as the original bits value. If you want to do the tests yourself then I have created a live conversion tool on my blog where you can do any of the 6 conversions listed above in real time (I have transcribed Bitcoin's <code>SetCompact()</code>, <code>GetDifficulty()</code> and <code>GetCompact()</code> into Javascript): <a href="https://analysis.null.place/how-do-the-bitcoin-mining-algorithms-work/#form7" rel="nofollow noreferrer">https://analysis.null.place/how-do-the-bitcoin-mining-algorithms-work/#form7</a></p>
<p>Note that numbers in Javascript are IEEE 754 double precision - the same precision as the difficulty in the Bitcoin source, so Javascript is as accurate as the Bitcoin source for all bits/difficulty/target conversions. However, to assuage scepticism I have also included the relevant unit tests from Bitcoin's <code>bitcoin/src/test/blockchain_tests.cpp</code> and <code>bitcoin/src/test/arith_uint256_tests.cpp</code> files on the blog just below the aforementioned tool - all tests pass.</p>

CC BY-SA 4.0
2018-11-13T13:12:53.590Z
2023-08-15T19:41:42.500Z
2023-08-15T19:41:42.500Z
mulllhausen
<p>I have written javascript code to understand Target, Difficulty and Avg Network Hashrate and how they are interlinked.</p>
<p>Difficulty = Difficulty_1_target / Current Target;</p>
<p>Difficulty_1_target is target when difficulty was 1, so its also called max target. which is defined in genesis block as a 4-byte number &quot;1d00ffff&quot;.
Target is found in block header as 4-byte number which is compact base256 notation, where first byte is exponent, and last three bytes are mantissa;</p>
<p>Next Difficulty = current difficulty * 2 weeks / T ( Time in which previous 2016 blocks found ).</p>
<p>So, if we know Difficulty, from the above equation we can find Current Target, using <a href="https://github.com/MikeMcl/bignumber.js/" rel="nofollow noreferrer">bignumber.js</a>:</p>
<pre class="lang-js prettyprint-override"><code>var base = new BigNumber(256);
var hTargetCompact = '1d00ffff';
var e = hTargetCompact.slice(0,2); //First Byte 
var exponent = new BigNumber(e,16);
exponent = exponent.minus(3); 

var m = hTargetCompact.slice(2); //Three Significant Bytes
var mantissa = new BigNumber(m,16);
var hTarget = mantissa.times(base.toPower(exponent));
var d = new BigNumber('2.87467423441594e12'); // Current Difficulty 2874674234415.94

var cTarget = hTarget.div(d).ceil();

// Output Current Target in Hex
console.log(cTarget.toString(16));  

// Current Target in compact format
mantissa = cTarget.toString(16).slice(0,6); // Most Significant three bytes
exponent = (cTarget.toString(16).length / 2).toString(16) // Exponent

var cTargetCompact = exponent + mantissa;
console.log(cTargetCompact);
</code></pre>
<p><a href="http://blog.kherwa.com/2017/10/25/blockchain-difficulty-network-hashrate/" rel="nofollow noreferrer">http://blog.kherwa.com/2017/10/25/blockchain-difficulty-network-hashrate/</a></p>
<p>Javascript code is on JSBin, you can try your combination also.</p>

CC BY-SA 3.0
2018-02-05T11:47:44.410Z
Welcome to Bitcoin.SE! A useful answer! I see you have already done the work here, but your answer can still be improved if you edit it to include some examples of how the equations work.
Willtech
CC BY-SA 4.0
2018-02-04T05:09:47.193Z
2023-08-15T19:47:15.700Z
2023-08-15T19:47:15.700Z
kherwa
<p>Answer shamelessly stolen from <a href="https://stackoverflow.com/a/22161019/530160">stackexchange</a>:</p>
<blockquote>
<p>Difficulty encoding is thoroughly described
<a href="https://en.bitcoin.it/wiki/Difficulty" rel="nofollow noreferrer">here</a>.</p>
<p>Hexadecimal representation like <code>0x182815ee</code> consists of two parts:</p>
<ul>
<li><code>0x18</code> -- number of bytes in a target</li>
<li><code>0x2815ee</code> -- target prefix</li>
</ul>
<p>This means that valid hash should be less than
<code>0x2815ee000000000000000000000000000000000000000000</code> (it is exactly
<code>0x18</code> = 24 bytes long).</p>
<p>Floating point representation of difficulty shows how much current
target is harder than the one used in the genesis block.</p>
<p>Satoshi decided to use <code>0x1d00ffff</code> as a difficulty for the genesis
block, so the target was
<code>0x00ffff0000000000000000000000000000000000000000000000000000</code>.</p>
<p>And 50810339.04827648 is how much current target is greater than the
initial one.</p>
</blockquote>
<p>How the Bitcoin client converts from bits -&gt; difficulty:</p>
<pre class="lang-cpp prettyprint-override"><code>uint256&amp; uint256::SetCompact(uint32_t nCompact, bool *pfNegative, bool *pfOverflow)
{
    int nSize = nCompact &gt;&gt; 24;
    uint32_t nWord = nCompact &amp; 0x007fffff;
    if (nSize &lt;= 3) {
        nWord &gt;&gt;= 8*(3-nSize);
        *this = nWord;
    } else {
        *this = nWord;
        *this &lt;&lt;= 8*(nSize-3);
    }
    if (pfNegative)
        *pfNegative = nWord != 0 &amp;&amp; (nCompact &amp; 0x00800000) != 0;
    if (pfOverflow)
        *pfOverflow = nWord != 0 &amp;&amp; ((nSize &gt; 34) ||
                                     (nWord &gt; 0xff &amp;&amp; nSize &gt; 33) ||
                                     (nWord &gt; 0xffff &amp;&amp; nSize &gt; 32));
    return *this;
}
</code></pre>
<p>How the Bitcoin client converts from difficulty -&gt; bits:</p>
<pre class="lang-cpp prettyprint-override"><code>uint32_t uint256::GetCompact(bool fNegative) const
{
    int nSize = (bits() + 7) / 8;
    uint32_t nCompact = 0;
    if (nSize &lt;= 3) {
        nCompact = GetLow64() &lt;&lt; 8*(3-nSize);
    } else {
        uint256 bn = *this &gt;&gt; 8*(nSize-3);
        nCompact = bn.GetLow64();
    }
    // The 0x00800000 bit denotes the sign.
    // Thus, if it is already set, divide the mantissa by 256 and increase the exponent.
    if (nCompact &amp; 0x00800000) {
        nCompact &gt;&gt;= 8;
        nSize++;
    }
    assert((nCompact &amp; ~0x007fffff) == 0);
    assert(nSize &lt; 256);
    nCompact |= nSize &lt;&lt; 24;
    nCompact |= (fNegative &amp;&amp; (nCompact &amp; 0x007fffff) ? 0x00800000 : 0);
    return nCompact;
}
</code></pre>
<p>Converting from target to difficulty, in shell. Create file <code>target-to-difficulty.sh</code>:</p>
<pre class="lang-bash prettyprint-override"><code>#!/bin/bash
echo &quot;ibase=16;FFFF0000000000000000000000000000000000000000000000000000 / $1&quot; | bc -l
</code></pre>
<p>Usage:</p>
<pre><code>$ ./target-to-difficulty.sh 000000000000000024DBE9000000000000000000000000000000000000000000
29829733124.04041574884510759883
</code></pre>

CC BY-SA 3.0
2014-09-15T16:17:27.347Z
Thanks for the code. However it only seems to convert between the 256 bit and 32 bit compact representation of bits. Not the floating point value of difficulty I am looking for. So I believe this is only part of the solution.
Dan
CC BY-SA 3.0
2014-09-15T19:40:54.447Z
@Dan To get the difficulty, divide the maximum target (bits=0x1d00ffff) by the current target.
theymos
CC BY-SA 4.0
2022-09-12T23:38:52.357Z
I know this is old, but what is pfNegative and pfOverflow?
chriscrutt
CC BY-SA 4.0
2022-09-13T16:43:09.373Z
@chriscrutt pf = pointer to flag. It means that the function checks whether the compact number is negative, or has an overflow (the exponent is so large that the result cannot fit in 256 bits.)
Nick ODell
CC BY-SA 4.0
2014-09-11T19:47:18.923Z
2023-07-21T15:11:14.893Z
2023-07-21T15:11:14.893Z
Nick ODell
<p>If we take block hash 0000000000000006770c3806960539ca83a24facbd99ea212f37f2a0e6a5629a for example.</p>

<p>The difficulty as a 32 bit float is <a href="http://explorer.chain.com/blocks/0000000000000006770c3806960539ca83a24facbd99ea212f37f2a0e6a5629a" rel="nofollow noreferrer">50810339.04827648</a>. The difficulty in bits as an unsigned 32 bit integer is <a href="https://blockchain.info/rawblock/0000000000000006770c3806960539ca83a24facbd99ea212f37f2a0e6a5629a" rel="nofollow noreferrer">424970034</a>?</p>

<p>What are the equations to go from difficulty -> bits and bits -> difficulty?</p>

CC BY-SA 3.0
2014-09-11T19:41:33.640Z
Related: http://stackoverflow.com/questions/22059359/trying-to-understand-nbits-value-from-stratum-protocol
Nick ODell
<blockchain><blockchain.info><block><difficulty>
What are the equations to convert between bits and difficulty?
Dan
# What are the equations to convert between bits and difficulty?

(Asked by: username_0 on 2014-09-11)

If we take block hash 0000000000000006770c3806960539ca83a24facbd99ea212f37f2a0e6a5629a for example.

The difficulty as a 32 bit float is [50810339.04827648](http://explorer.chain.com/blocks/0000000000000006770c3806960539ca83a24facbd99ea212f37f2a0e6a5629a). The difficulty in bits as an unsigned 32 bit integer is [424970034](https://blockchain.info/rawblock/0000000000000006770c3806960539ca83a24facbd99ea212f37f2a0e6a5629a)?

What are the equations to go from difficulty -> bits and bits -> difficulty?

**Tags:** blockchain, blockchain.info, block, difficulty

> **Comments:**
> **username_1**: Related: http://stackoverflow.com/questions/22059359/trying-to-understand-nbits-value-from-stratum-protocol  

---

## 3 answers

### Answer by username_1 on 2014-09-11. Score: 23 | Accepted answer

Answer shamelessly stolen from [stackexchange](https://stackoverflow.com/a/22161019/530160):

> Difficulty encoding is thoroughly described
> [here](https://en.bitcoin.it/wiki/Difficulty).
>
> Hexadecimal representation like `0x182815ee` consists of two parts:
>
> * `0x18` -- number of bytes in a target
> * `0x2815ee` -- target prefix
>
> This means that valid hash should be less than
> `0x2815ee000000000000000000000000000000000000000000` (it is exactly
> `0x18` = 24 bytes long).
>
> Floating point representation of difficulty shows how much current
> target is harder than the one used in the genesis block.
>
> Satoshi decided to use `0x1d00ffff` as a difficulty for the genesis
> block, so the target was
> `0x00ffff0000000000000000000000000000000000000000000000000000`.
>
> And 50810339.04827648 is how much current target is greater than the
> initial one.

How the Bitcoin client converts from bits -> difficulty:

```cpp
uint256& uint256::SetCompact(uint32_t nCompact, bool *pfNegative, bool *pfOverflow)
{
    int nSize = nCompact >> 24;
    uint32_t nWord = nCompact & 0x007fffff;
    if (nSize <= 3) {
        nWord >>= 8*(3-nSize);
        *this = nWord;
    } else {
        *this = nWord;
        *this <<= 8*(nSize-3);
    }
    if (pfNegative)
        *pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0;
    if (pfOverflow)
        *pfOverflow = nWord != 0 && ((nSize > 34) ||
                                     (nWord > 0xff && nSize > 33) ||
                                     (nWord > 0xffff && nSize > 32));
    return *this;
}

```

How the Bitcoin client converts from difficulty -> bits:

```cpp
uint32_t uint256::GetCompact(bool fNegative) const
{
    int nSize = (bits() + 7) / 8;
    uint32_t nCompact = 0;
    if (nSize <= 3) {
        nCompact = GetLow64() << 8*(3-nSize);
    } else {
        uint256 bn = *this >> 8*(nSize-3);
        nCompact = bn.GetLow64();
    }
    // The 0x00800000 bit denotes the sign.
    // Thus, if it is already set, divide the mantissa by 256 and increase the exponent.
    if (nCompact & 0x00800000) {
        nCompact >>= 8;
        nSize++;
    }
    assert((nCompact & ~0x007fffff) == 0);
    assert(nSize < 256);
    nCompact |= nSize << 24;
    nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0);
    return nCompact;
}

```

Converting from target to difficulty, in shell. Create file `target-to-difficulty.sh`:

```bash
#!/bin/bash
echo "ibase=16;FFFF0000000000000000000000000000000000000000000000000000 / $1" | bc -l

```

Usage:

```
$ ./target-to-difficulty.sh 000000000000000024DBE9000000000000000000000000000000000000000000
29829733124.04041574884510759883

```

> **Comments:**
> **username_0**: Thanks for the code. However it only seems to convert between the 256 bit and 32 bit compact representation of bits. Not the floating point value of difficulty I am looking for. So I believe this is only part of the solution.  
> **username_5**: @username_0 To get the difficulty, divide the maximum target (bits=0x1d00ffff) by the current target.  
> **username_6**: I know this is old, but what is pfNegative and pfOverflow?  
> **username_1**: @username_6 pf = pointer to flag. It means that the function checks whether the compact number is negative, or has an overflow (the exponent is so large that the result cannot fit in 256 bits.)  

---

### Answer by username_2 on 2018-11-13. Score: 4

There are 3 representations of the same thing (with varying degrees of precision) in Bitcoin:

* bits - unsigned int 32-bit
* target - unsigned int 256-bit
* difficulty - double-precision float (64-bit)

and 6 methods are necessary to convert between any two of these:

* bits -> target (`SetCompact()` in `bitcoin/src/arith_uint256.cpp`)
* bits -> difficulty (`GetDifficulty()` in `bitcoin/src/rpc/blockchain.cpp`)
* target -> bits (`GetCompact()` in `bitcoin/src/arith_uint256.cpp`)
* target -> difficulty (same as target -> bits -> difficulty)
* difficulty -> bits (not done in `bitcoin/src`)
* difficulty -> target (same as difficulty -> bits -> target)

The Bitcoin source code can do the conversion from bits -> difficulty as asked in the question, but cannot do the conversion from difficulty -> bits as also asked in the question.

I have written my own implementation of the difficulty -> bits conversion in vanilla Javascript by mimicking the target -> bits conversion where possible, plus some additional checks:

```js
function difficulty2bits(difficulty) { 
    if (difficulty < 0) throw 'difficulty cannot be negative';
    if (!isFinite(difficulty)) throw 'difficulty cannot be infinite';
    for (var shiftBytes = 1; true; shiftBytes++) {
        var word = (0x00ffff * Math.pow(0x100, shiftBytes)) / difficulty;
        if (word >= 0xffff) break;
    }
    word &= 0xffffff; // convert to int < 0xffffff
    var size = 0x1d - shiftBytes;
    // the 0x00800000 bit denotes the sign, so if it is already set, divide the
    // mantissa by 0x100 and increase the size by a byte
    if (word & 0x800000) {
        word >>= 8;
        size++;
    }
    if ((word & ~0x007fffff) != 0) throw 'the \'bits\' \'word\' is out of bounds';
    if (size > 0xff) throw 'the \'bits\' \'size\' is out of bounds';
    var bits = (size << 24) | word;
    return bits;
}

```

It is possible to validate that the above function gives correct answers by doing the following conversion:

```
bits -> difficulty -> bits

```

Where bits -> difficulty is done using Bitcoin's `GetDifficulty()` and difficulty -> bits is done using `difficulty2bits()` above. If we arrive back at the same bits value then the `difficulty2bits()` function is correct. The only exception is when `(bits & 0x00800000) != 0`, since this means that bits is a negative number, whereas difficulty is always a positive number in Bitcoin.

I have tested the above `difficulty2bits()` function and it does return the same result as the original bits value. If you want to do the tests yourself then I have created a live conversion tool on my blog where you can do any of the 6 conversions listed above in real time (I have transcribed Bitcoin's `SetCompact()`, `GetDifficulty()` and `GetCompact()` into Javascript): <https://analysis.null.place/how-do-the-bitcoin-mining-algorithms-work/#form7>

Note that numbers in Javascript are IEEE 754 double precision - the same precision as the difficulty in the Bitcoin source, so Javascript is as accurate as the Bitcoin source for all bits/difficulty/target conversions. However, to assuage scepticism I have also included the relevant unit tests from Bitcoin's `bitcoin/src/test/blockchain_tests.cpp` and `bitcoin/src/test/arith_uint256_tests.cpp` files on the blog just below the aforementioned tool - all tests pass.


---

### Answer by username_3 on 2018-02-04. Score: 3

I have written javascript code to understand Target, Difficulty and Avg Network Hashrate and how they are interlinked.

Difficulty = Difficulty\_1\_target / Current Target;

Difficulty\_1\_target is target when difficulty was 1, so its also called max target. which is defined in genesis block as a 4-byte number "1d00ffff".
Target is found in block header as 4-byte number which is compact base256 notation, where first byte is exponent, and last three bytes are mantissa;

Next Difficulty = current difficulty \* 2 weeks / T ( Time in which previous 2016 blocks found ).

So, if we know Difficulty, from the above equation we can find Current Target, using [bignumber.js](https://github.com/MikeMcl/bignumber.js/):

```js
var base = new BigNumber(256);
var hTargetCompact = '1d00ffff';
var e = hTargetCompact.slice(0,2); //First Byte 
var exponent = new BigNumber(e,16);
exponent = exponent.minus(3); 

var m = hTargetCompact.slice(2); //Three Significant Bytes
var mantissa = new BigNumber(m,16);
var hTarget = mantissa.times(base.toPower(exponent));
var d = new BigNumber('2.87467423441594e12'); // Current Difficulty 2874674234415.94

var cTarget = hTarget.div(d).ceil();

// Output Current Target in Hex
console.log(cTarget.toString(16));  

// Current Target in compact format
mantissa = cTarget.toString(16).slice(0,6); // Most Significant three bytes
exponent = (cTarget.toString(16).length / 2).toString(16) // Exponent

var cTargetCompact = exponent + mantissa;
console.log(cTargetCompact);

```

<http://blog.username_3.com/2017/10/25/blockchain-difficulty-network-hashrate/>

Javascript code is on JSBin, you can try your combination also.

> **Comments:**
> **username_4**: Welcome to Bitcoin.SE! A useful answer! I see you have already done the work here, but your answer can still be improved if you edit it to include some examples of how the equations work.  

---

