你能解释一下这个Math.Log10与BigInteger.Log10的行为吗?

moo*_*oop 4 .net c# floating-point biginteger

有人可以解释以下System.Numerics.BigInteger行为吗?

Console.WriteLine(Math.Log10(100));       // prints 2
Console.WriteLine(Math.Log10(1000));      // prints 3 (as expected)

Console.WriteLine((int)Math.Log10(100));  // prints 2
Console.WriteLine((int)Math.Log10(1000)); // prints 3 (as axpected)

var bi100 = new BigInteger(100);
var bi1000 = new BigInteger(1000);

Console.WriteLine(BigInteger.Log10(bi100));       // prints 2
Console.WriteLine(BigInteger.Log10(bi1000));      // prints 3 (as axpected) 

Console.WriteLine((int)BigInteger.Log10(bi100));  // prints 2
Console.WriteLine((int)BigInteger.Log10(bi1000)); // prints 2 ???????

Console.WriteLine(Math.Floor(BigInteger.Log10(bi100)));   // prints 2
Console.WriteLine(Math.Floor(BigInteger.Log10(bi1000)));  // prints 2 ???????

Console.WriteLine(Math.Round(BigInteger.Log10(bi100)));  // prints 2
Console.WriteLine(Math.Round(BigInteger.Log10(bi1000))); // prints 3 (as expected)
Run Code Online (Sandbox Code Playgroud)

编辑:请注意,我知道这是一个问题.我想知道为什么 Math.Log10和BigInteger.Log10的行为有所不同.

Mit*_*eat 6

这是由于精度和圆度.

这一行:

Console.WriteLine((int)BigInteger.Log10(bi1000)); 
Run Code Online (Sandbox Code Playgroud)

将值2.9999999999999996向下舍入为2,而Console.WriteLine将其写为3

您可以使用中间double变量验证这一点,并检查其值:

double x = BigInteger.Log10(bi1000);
Console.WriteLine((int)x);  
Run Code Online (Sandbox Code Playgroud)

  • 这不是一个有效的答案.它没有解释**为什么**Math.Log10和BigInteger.Log10的行为有所不同!请扩展或删除你的答案! (2认同)