# What are the equations to convert between bits and difficulty?

If we take block hash 0000000000000006770c3806960539ca83a24facbd99ea212f37f2a0e6a5629a for example.

The difficulty as a 32 bit float is 50810339.04827648. The difficulty in bits as an unsigned 32 bit integer is 424970034?

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

Answer shamelessly stolen from stackexchange:

Difficulty encoding is thoroughly described here.

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:

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

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

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

Usage:

``````\$ ./target-to-difficulty.sh 000000000000000024DBE9000000000000000000000000000000000000000000
29829733124.04041574884510759883
``````
• 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 Sep 15 '14 at 16:17
• @Dan To get the difficulty, divide the maximum target (bits=0x1d00ffff) by the current target. – theymos Sep 15 '14 at 19:40

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:

``````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.kherwa.com/2017/10/25/blockchain-difficulty-network-hashrate/

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

• 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 Feb 5 '18 at 11:47

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:

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