Можете ли вы объяснить это поведение Math.Log10 против BigInteger.Log10? - PullRequest
4 голосов
/ 20 февраля 2011

Может кто-нибудь объяснить следующее 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 и BigInteger.Log10 отличается.

Ответы [ 3 ]

6 голосов
/ 20 февраля 2011

Это связано с точностью и округлением.

Эта строка:

Console.WriteLine((int)BigInteger.Log10(bi1000)); 

округляет значение 2.9999999999999996 до 2, тогда как Console.WriteLine записывает это значение как 3

Вы можете проверить это, используя промежуточную переменную double и проверив ее значение:

double x = BigInteger.Log10(bi1000);
Console.WriteLine((int)x);  
1 голос
/ 22 февраля 2011

Большая разница в том, что BigInteger.Log10(x) реализован как Math.Log(x)/Math.Log(10), тогда как Math.Log10(x) реализован по-другому (это extern, так что это не легко понять). Несмотря на это, должно быть очевидно, что они используют слегка отличающиеся алгоритмы для выполнения логарифма по основанию-10, что вызывает небольшую разницу в выходных данных.

0 голосов
/ 22 февраля 2011

Поведение отличается, потому что это разные типы с разными представлениями и разными реализациями.

...