Bitcoin Forum
April 28, 2017, 03:53:12 PM *
News: Latest stable version of Bitcoin Core: 0.14.1  [Torrent]. (New!)
 
   Home   Help Search Donate Login Register  
Pages: [1]
  Print  
Author Topic: fast difficulty calculation from bits  (Read 873 times)
mizerydearia
Hero Member
*****
Offline Offline

Activity: 574



View Profile
August 20, 2011, 12:28:28 PM
 #1

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

update: Links added by miz
1493394792
Hero Member
*
Offline Offline

Posts: 1493394792

View Profile Personal Message (Offline)

Ignore
1493394792
Reply with quote  #2

1493394792
Report to moderator
1493394792
Hero Member
*
Offline Offline

Posts: 1493394792

View Profile Personal Message (Offline)

Ignore
1493394792
Reply with quote  #2

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

Posts: 1493394792

View Profile Personal Message (Offline)

Ignore
1493394792
Reply with quote  #2

1493394792
Report to moderator
1493394792
Hero Member
*
Offline Offline

Posts: 1493394792

View Profile Personal Message (Offline)

Ignore
1493394792
Reply with quote  #2

1493394792
Report to moderator
graingert
Full Member
***
Offline Offline

Activity: 227


View Profile WWW
August 20, 2011, 08:11:00 PM
 #2

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

Sounds like....

Taylor Swift...

 *Image Removed*
etotheipi
Legendary
*
expert
Offline Offline

Activity: 1428


Core Armory Developer


View Profile WWW
August 21, 2011, 07:42:33 PM
 #3

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]
  Print  
 
Jump to:  

Sponsored by , a Bitcoin-accepting VPN.
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!