This is due to accuracy and rounding.
This line:
Console.WriteLine((int)BigInteger.Log10(bi1000));
rounds the value 2.999999999999999696 to 2, whereas it Console.WriteLinewrites it as 3
You can check this with an intermediate variable doubleand check its value:
double x = BigInteger.Log10(bi1000);
Console.WriteLine((int)x);
source
share