C# 你能解释一下Math.Log10和BigInteger.Log10的行为吗?

C# 你能解释一下Math.Log10和BigInteger.Log10的行为吗?,c#,.net,floating-point,biginteger,C#,.net,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(1

有人能解释一下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)

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

这是由于精度和舍入造成的

这一行:

Console.WriteLine((int)BigInteger.Log10(bi1000)); 
将值2.9999999999996四舍五入为2,而
Console.WriteLine
将其写为3

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

double x = BigInteger.Log10(bi1000);
Console.WriteLine((int)x);  

行为不同,因为它们是不同的类型,具有不同的表示和不同的实现。

最大的区别在于
biginger.Log10(x)
实现为
Math.Log(x)/Math.Log(10)
,而
Math.Log10(x)
实现方式不同(这是一个
extern
,所以不容易理解)。无论如何,很明显,他们使用的算法略有不同,以10为底的对数计算,这会导致输出略有不同。

最后一行的代码注释不正确:Prints 3(至少对我来说)-1,因为“3不能精确地表示为二进制”是完全错误的。所有操作数都是精确的。但是一些中间值可能不精确,这取决于对数函数的实现方式。Cheers Ben。更正。我正试图更准确地说你所说的。这不是一个有效的答案。它无法解释Math.Log10和BigInteger.Log10行为不同的原因!请扩展或删除您的答案!这确实解释了原因。它们正在执行相同的操作,但类型不同,因此具有不同的精度和舍入问题。如果输入相同,您希望两种方法始终生成相同的结果?如果是,为什么有两种方法?这确实解释了为什么会发生这种情况。Console.WriteLine向上取整(在本例中),(int)向下截断。您还需要知道什么?(CW,因为这是一个糟糕问题的糟糕答案。)关于舍入问题的任何问题都不会有好的结局。@Lasse V.Karlsen,因为这是一个舍入问题,但问题明确排除了这一点作为答案。它本质上是问为什么两个不同的东西是不同的。但差异是一个舍入问题。涉及到两段不同的代码,它们传播的舍入错误不同至少是其中一个区别。