I'm trying to understand how the >>=
operation in nSubsidy >>= (nBestHeight / 210000);
actually cuts the subsidy in half every 4 years on Bitcoin v0.01.
It is clear how 210000 blocks average out to around 4 years and how dividing the last block height will return an integer that will give us the number of time it needs to be halved. What is confusing is how just shifting a bit on nSubsidy
will give us the desired subsidy.
I wrote this loop to help visualize the shift in bits but still unclear how in binary, a simple 1 bit shift gets us the desired result.
#include <iostream>
#include <bitset>
int main()
{
uint64_t COIN = 100000000;
uint64_t nSubsidy;
std::string binary;
//halving and non halving block height examples
uint64_t nBestHeight[] = {-1, 0, 1, 210000, 210001, 420000, 420001, 630000, 630001, 840000, 840001, 1050000, 1050001};
for(unsigned int a = 0; a < sizeof(nBestHeight)/sizeof(nBestHeight[0]); a = a + 1 )
{
nSubsidy = 50 * COIN;
//Shift bits
nSubsidy >>= (nBestHeight[a] / 210000);
//Convert to binary to visualize bit shift
binary = std::bitset<64>(nSubsidy).to_string();
std::cout << "nSubsidy (64 bit binary) = " << binary << " | (nBestHeight/210000) = " << (nBestHeight[a] / 210000) << " | nSubsidy = " << nSubsidy << " | nBestHeight = " << nBestHeight[a] << "\n";
}
}
/*
OUTPUT
BINARY TO VISUALIZE BIT SHIFT HALVING ERA MINING REWARD CURRENT BLOCK HEIGHT
nSubsidy (64 bit binary) = 0000000000000000000000000000000100101010000001011111001000000000 | (nBestHeight/210000) = 0 | nSubsidy = 5000000000 | nBestHeight = 0
nSubsidy (64 bit binary) = 0000000000000000000000000000000100101010000001011111001000000000 | (nBestHeight/210000) = 0 | nSubsidy = 5000000000 | nBestHeight = 1
nSubsidy (64 bit binary) = 0000000000000000000000000000000010010101000000101111100100000000 | (nBestHeight/210000) = 1 | nSubsidy = 2500000000 | nBestHeight = 210000
nSubsidy (64 bit binary) = 0000000000000000000000000000000010010101000000101111100100000000 | (nBestHeight/210000) = 1 | nSubsidy = 2500000000 | nBestHeight = 210001
nSubsidy (64 bit binary) = 0000000000000000000000000000000001001010100000010111110010000000 | (nBestHeight/210000) = 2 | nSubsidy = 1250000000 | nBestHeight = 420000
nSubsidy (64 bit binary) = 0000000000000000000000000000000001001010100000010111110010000000 | (nBestHeight/210000) = 2 | nSubsidy = 1250000000 | nBestHeight = 420001
nSubsidy (64 bit binary) = 0000000000000000000000000000000000100101010000001011111001000000 | (nBestHeight/210000) = 3 | nSubsidy = 625000000 | nBestHeight = 630000
nSubsidy (64 bit binary) = 0000000000000000000000000000000000100101010000001011111001000000 | (nBestHeight/210000) = 3 | nSubsidy = 625000000 | nBestHeight = 630001
nSubsidy (64 bit binary) = 0000000000000000000000000000000000010010101000000101111100100000 | (nBestHeight/210000) = 4 | nSubsidy = 312500000 | nBestHeight = 840000
nSubsidy (64 bit binary) = 0000000000000000000000000000000000010010101000000101111100100000 | (nBestHeight/210000) = 4 | nSubsidy = 312500000 | nBestHeight = 840001
nSubsidy (64 bit binary) = 0000000000000000000000000000000000001001010100000010111110010000 | (nBestHeight/210000) = 5 | nSubsidy = 156250000 | nBestHeight = 1050000
nSubsidy (64 bit binary) = 0000000000000000000000000000000000001001010100000010111110010000 | (nBestHeight/210000) = 5 | nSubsidy = 156250000 | nBestHeight = 1050001
*/
Is it really that just by shifting a bit to right or to the left we duplicate or half the value? Are there any resources or any other terminology to verify this better? Are the above assumptions even right?