Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: mizerydearia on August 20, 2011, 12:28:28 PM



Title: fast difficulty calculation from bits
Post by: mizerydearia on August 20, 2011, 12:28:28 PM
Hey genjix (https://bitcointalk.org/index.php?action=profile;u=1931) here, I'm posting as mizerydearia (https://bitcointalk.org/index.php?action=profile;u=338) since I'm not logged in ... blaa blaa

Here;s a fast way to calculate difficulty. It uses a modified taylor series (http://en.wikipedia.org/wiki/Taylor_series) for the logarithm (you can see tutorials on flipcode (http://flipcode.com/) 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 (https://gitorious.org/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


Title: Re: fast difficulty calculation from bits
Post by: graingert on August 20, 2011, 08:11:00 PM
so it's fast, and it uses a
modified taylor series
?

Sounds like....

Taylor Swift...


Title: Re: fast difficulty calculation from bits
Post by: etotheipi on 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.