Bitcoin Forum
November 13, 2024, 05:36:07 PM *
News: Latest Bitcoin Core release: 28.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: slight error in difficulty computation  (Read 1334 times)
Enzo (OP)
Newbie
*
Offline Offline

Activity: 14
Merit: 0


View Profile
May 26, 2011, 02:06:21 PM
 #1

I don't understand this:

$ curl --url http://***:***@127.0.0.1:8332 -H 'content-type: text/plain;'  --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getwork", "params": [] }'
{"result":{"midstate":"df92c2b8aac64fc5d15a0ff08a8950453ce9e8fb1ecfa39cb8aeaca78bae173a","data":"0000000174dae8b4ae722300d81693b97993f4a57dc7c8151b980d4a00003bfc00000000b79f998 e1df8db02f7d2ba1676e7060a57fa8a5764990629f53173f8b61d8c1f4dde5b591a44b9f2000000 0000000080000000000000000000000000000000000000000000000000000000000000000000000 0000000000080020000","hash1":"0000000000000000000000000000000000000000000000000000000000000000000000800000000 0000000000000000000000000000000000000000000010000","target":"0000000000000000000000000000000000000000000000f2b944000000000000"},"error":null,"id":"curltest"}

$ curl --url http://***.***@127.0.0.1:8332 -H 'content-type: text/plain;'  --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getdifficulty", "params": [] }'
{"result":244139.48158254,"error":null,"id":"curltest"}

$ echo "base=10;ibase=16;scale=8;00000000FFFF0000000000000000000000000000000000000000000000000000 / 00000000000044B9F20000000000000000000000000000000000000000000000" |bc
244112.48777433


Why I get 244112.48777433 instead of 244139.48158254 ?

Enzo

realnowhereman
Hero Member
*****
Offline Offline

Activity: 504
Merit: 502



View Profile
May 28, 2011, 10:15:49 AM
 #2

Because bc is better at arbitrary precision floating point calculation than bitcoin.

Bitcoin uses an approximation:

Code:
double GetDifficulty()
{
    // Floating point number that is a multiple of the minimum difficulty,
    // minimum difficulty = 1.0.
    if (pindexBest == NULL)
        return 1.0;
    int nShift = 256 - 32 - 31; // to fit in a uint
    double dMinimum = (CBigNum().SetCompact(bnProofOfWorkLimit.GetCompact()) >> nShift).getuint();
    double dCurrently = (CBigNum().SetCompact(pindexBest->nBits) >> nShift).getuint();
    return dMinimum / dCurrently;
}

In case its not clear, it doesn't use the most significant bits, it just shifts the bignums representing the current target and the minimum target down by a fixed number of bits, and then divides those numbers to get a floating point answer.  It's not the best approximation for two reasons:

  • It potentially throws away resolution by assuming knowledge of the minimum target.  Fortunately that assumption is true.
  • Doubles contain more than 32 bits worth of precision, and the division is done with two 32 bit integers.

Short of implementing a full arbitrary precision floating point division (which isn't trivial), this psuedo code might be better:

Code:
unsigned int hb1, hb2;
hb1 = highest_bit( proofOfWorkLimit );
hb2 = highest_bit( currentTarget );
if( hb2 > hb1 )
  hb1 = hb2;
hb1 -= bits_of_precision_in_double;

uint64_t L = proofOfWorkLimit >> hb1;
uint64_t T = currentTarget >> hb1;

return (double)(L)/T;

To be honest though, there's no real reason to change it.  It's only used for displaying to users, never for calculations.  Other than for pride, there's no pressing need to fix it.

1AAZ4xBHbiCr96nsZJ8jtPkSzsg1CqhwDa
Pieter Wuille
Legendary
*
qt
Offline Offline

Activity: 1072
Merit: 1181


View Profile WWW
May 28, 2011, 10:24:41 AM
 #3

There's already a patch to fix it, see https://github.com/bitcoin/bitcoin/pull/276

I do Bitcoin stuff.
Enzo (OP)
Newbie
*
Offline Offline

Activity: 14
Merit: 0


View Profile
May 28, 2011, 02:37:21 PM
 #4


Because bc is better at arbitrary precision floating point calculation than bitcoin.

So I stumbled upon a bug in bitclient (a minor bug, obviously) Smiley
I would like to  point out that there's no need of an high precision calculator: target is a big number but with few significant digits. The maximum target has only 4  significant hex digits (FFFF), I don't know how many there are in the current target but I suppose there's no need for it to have many more.
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!