Bitcoin Forum
May 22, 2018, 10:01:17 PM
 News: Latest stable version of Bitcoin Core: 0.16.0  [Torrent]. (New!)
 Home Help Search Donate Login Register
 Pages: [1]
 Author Topic: fast difficulty calculation from bits  (Read 958 times)
mizerydearia
Hero Member

Offline

Activity: 574
Merit: 500

 August 20, 2011, 12:28:28 PM

Hey genjix here, I'm posting as mizerydearia since I'm not logged in ... blaa blaa

Here;s a fast way to calculate difficulty. It uses a modified taylor series for the logarithm (you can see tutorials on flipcode and wikipedia) and relies on logs to transform the difficulty calculation:

Code:
#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;
}

Unfortunately I don't have much use for it in libbitcoin. Maybe some miner will find it useful.

To see the math to go from the normal difficulty calculations (which require large big ints bigger than the space in any normal integer) to the calculation above, here's some python:

Code:
import decimal, math
l = math.log
e = math.e

print 0x00ffff * 2**(8*(0x1d - 3)) / float(0x0404cb * 2**(8*(0x1b - 3)))
print l(0x00ffff * 2**(8*(0x1d - 3)) / float(0x0404cb * 2**(8*(0x1b - 3))))
print l(0x00ffff * 2**(8*(0x1d - 3))) - l(0x0404cb * 2**(8*(0x1b - 3)))
print l(0x00ffff) + l(2**(8*(0x1d - 3))) - l(0x0404cb) - l(2**(8*(0x1b - 3)))
print l(0x00ffff) + (8*(0x1d - 3))*l(2) - l(0x0404cb) - (8*(0x1b - 3))*l(2)
print l(0x00ffff / float(0x0404cb)) + (8*(0x1d - 3))*l(2) - (8*(0x1b - 3))*l(2)
print l(0x00ffff / float(0x0404cb)) + (0x1d - 0x1b)*l(2**8)

Cya

1527026477
Hero Member

Offline

Posts: 1527026477

Ignore
 1527026477

1527026477
 Report to moderator
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction. Advertise here.
1527026477
Hero Member

Offline

Posts: 1527026477

Ignore
 1527026477

1527026477
 Report to moderator
1527026477
Hero Member

Offline

Posts: 1527026477

Ignore
 1527026477

1527026477
 Report to moderator
graingert
Full Member

Offline

Activity: 227
Merit: 100

 August 20, 2011, 08:11:00 PM

so it's fast, and it uses a
modified taylor series
?

Sounds like....

Taylor Swift...

*Image Removed*
etotheipi
Legendary

Offline

Activity: 1428
Merit: 1000

Core Armory Developer

 August 21, 2011, 07:42:33 PM

Why not just use the conversion that's in the C++ code?  So far, it's the only piece of the reference client that I've been able to understand enough to implement:

Code:
def difficultyBits_to_float(b):
i = binary_to_int(b)
nShift = (i >> 24) & 0xff
dDiff = float(0x0000ffff) / float(i & 0x00ffffff)
while nShift < 29:
dDiff *= 256.0
nShift += 1
while nShift > 29:
dDiff /= 256.0
nShift -= 1
return dDiff

Actually, what I really need is the conversion back to bit-representation.  For whatever reason, I never found it, and never bothered to try to figure it out.

Founder and CEO of Armory Technologies, Inc.
Armory Bitcoin Wallet: Bringing cold storage to the average user!
Only use Armory software signed by the Armory Offline Signing Key (0x98832223)

Please donate to the Armory project by clicking here!    (or donate directly via 1QBDLYTDFHHZAABYSKGKPWKLSXZWCCJQBX -- yes, it's a real address!)
 Pages: [1]
 « previous topic next topic »