# 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?

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.