C# 你能解释一下Math.Log10和BigInteger.Log10的行为吗?
有人能解释一下System.Numerics.BigInteger的行为吗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
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,因为这是一个舍入问题,但问题明确排除了这一点作为答案。它本质上是问为什么两个不同的东西是不同的。但差异是一个舍入问题。涉及到两段不同的代码,它们传播的舍入错误不同至少是其中一个区别。