# I get exactly 21.000.000 coins.

#### Aayan

##### Member
I had read somewhere that the number of bitcoins is equal with 20.999.??? but not exactly 21M.

I wrote this on PHP:
https://pastebin.com/raw/xdruWaBJ

and I get exactly 21 million coins when I run the file. Do I do anything wrong?

#### Toby

##### New member
It's important to note that whilst the total theoretical coin cap is 21 million, it will never be 21 million. If it's a graph, the 21 million is an asymptote and the graph will tend towards it.

The reason that it will never be 21 million is because the halving is never exactly accurate; Bitcoin has only 8 decimals and at some point in time, the halving of the rewards will result in a scenario such that the reward extends beyond that 8 decimals, resulting in some coins being lost.

Fun fact, the actual Bitcoin will not go into the full 20.9 million that people estimate.

#### Aayan

##### Member
Fun fact, the actual Bitcoin will not go into the full 20.9 million that people estimate.
What? why?

#### Juelz

##### New member
it is probably because your "num" is not of type integer, it is instead of type float and at some point when it is divided by 2 it has a leftover 0.5 which should be discarded since it is outside of the valid range but it is not.
you are also using 50 as your start which is technically wrong. it should be 5000000000 as a UInt64 (an unsigned 64-bit number without decimal places) and shift it right on each halving. https://github.com/bitcoin/bitcoin/blob/master/src/validation.cpp#L1242-L1253

#### Aayan

##### Member
it is probably because your "num" is not of type integer, it is instead of type float and at some point when it is divided by 2 it has a leftover 0.5 which should be discarded since it is outside of the valid range but it is not.
you are also using 50 as your start which is technically wrong. it should be 5000000000 as a UInt64 (an unsigned 64-bit number without decimal places) and shift it right on each halving. https://github.com/bitcoin/bitcoin/blob/master/src/validation.cpp#L1242-L1253
True, I now write it in satoshis instead of bitcoins: https://pastebin.com/raw/ubfCTNDY
I don't think I've done anything wrong now.

It returns me 2099999999877764 satoshis.

The number_format function solves the 0.5 problem, even if I don't fully understand what is the problem you're saying.

#### Jordy

##### New member
even if I don't fully understand what is the problem you're saying.
the problem is very simple and is about the variable types. i am not familiar with PHP and am not sure if you can define a fixed variable type that doesn't change. but in programming if you define an "integer" like 7 and divide it by 2 the result will be 3 but if you define a float/decimal like 7 and divide it by 2 the result will be 3.5.

C# example

#### Aayan

##### Member
the problem is very simple and is about the variable types. i am not familiar with PHP and am not sure if you can define a fixed variable type that doesn't change. but in programming if you define an "integer" like 7 and divide it by 2 the result will be 3 but if you define a float/decimal like 7 and divide it by 2 the result will be 3.5.

C# example
As far as I know, in C# you define:
int num1;
float num2;

In php, it's not like that. You define just a "var":
var floatName = 7;
var intName = 7;

You can't divide intName / 2 and return 3. It will return you 3,5. Although, there are functions that will return 3 instead.

#### Anakin

##### New member
As far as I know, in C# you define:
int num1;
float num2;

In php, it's not like that. You define just a "var":
var floatName = 7;
var intName = 7;

You can't divide intName / 2 and return 3. It will return you 3,5. Although, there are functions that will return 3 instead.
IIRC PHP dynamically converts between types as it sees fit (like JavaScript), which is for example why you can concatenate numbers like you would concatenate strings (eg. 1 . 2 = 12). For numbers this means that PHP will use integers or (double) floating point numbers depending on the operation.

Thing is though that floating point numbers have limited precision and are stored in a way that work better for some numbers than for others so you can get the weirdest rounding errors.

For example your calculations may return 0.1 + 0.2 = 0.30000000000000004 (which some script interpreters may account for when converting the number to a string). The more complex and longer your calculations the more those rounding errors accumulate so eventually your calculations end up way off.

For reference:
https://floating-point-gui.de/
https://en.wikipedia.org/wiki/Round-off_error