Skip to content

Instantly share code, notes, and snippets.

@Viswanathantv
Created November 27, 2013 16:50
Show Gist options
  • Save Viswanathantv/7679067 to your computer and use it in GitHub Desktop.
Save Viswanathantv/7679067 to your computer and use it in GitHub Desktop.
Difficulty calculation
#include <iostream>
#include <cmath>
inline float fast_log(float val)
{
int * const exp_ptr = reinterpret_cast <int *>(&val);
int x = *exp_ptr;
const int log_2 = ((x >> 23) & 255) - 128;
x &= ~(255 << 23);
x += 127 << 23;
*exp_ptr = x;
val = ((-1.0f/3) * val + 2) * val - 2.0f/3;
return ((val + log_2) * 0.69314718f);
}
float difficulty(unsigned int bits)
{
static double max_body = fast_log(0x00ffff), scaland = fast_log(256);
return exp(max_body - fast_log(bits & 0x00ffffff) + scaland * (0x1d - ((bits & 0xff000000) >> 24)));
}
int main()
{
std::cout << difficulty(0x1b0404cb) << std::endl;
return 0;
}
Note :
difficulty = maximum_target / current_target (target is a 256 bit number)
Each block stores a packed representation (called "Bits") for its actual hexadecimal target. The target can be derived from it via a predefined formula.
For example, if the packed target in the block is 0x1b0404cb, the hexadecimal target is
0x0404cb * 2**(8*(0x1b - 3)) = 0x00000000000404CB000000000000000000000000000000000000000000000000
Note that the 0x0404cb value is a signed value in this format. The largest legal value for this field is 0x7fffff. To make a larger value you must shift it down one full byte. Also 0x008000 is the smallest positive valid value.
The highest possible target (difficulty 1) is defined as 0x1d00ffff, which gives us a hex target of
0x00ffff * 2**(8*(0x1d - 3)) = 0x00000000FFFF0000000000000000000000000000000000000000000000000000
It should be noted that pooled mining often uses non-truncated targets, which puts "pool difficulty 1" at
0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
So the difficulty at 0x1b0404cb is therefore:
0x00000000FFFF0000000000000000000000000000000000000000000000000000 /
0x00000000000404CB000000000000000000000000000000000000000000000000
= 16307.420938523983 (bdiff)
And:
0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF /
0x00000000000404CB000000000000000000000000000000000000000000000000
= 16307.669773817162 (pdiff)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment