Нужно производить простые арифметические действия над большими числами на C#. Использовал библиотеку System.Numerics. Но он не верно считает. Например
BigInteger first = BigInteger.Parse("1459141956031776814097256491377265401586541003894843279763498785157880955654141795");
BigInteger second = BigInteger.Parse("22248470822666314938692568397119675677137950638191323448941735236079264477232");
BigInteger result = first / second;
Получаю результат = 65583. Теперь если число из переменной first разделить на 65583 должно получиться число second, но это не так, получается совершенно другое число. Как реализовать, чтобы правильно посчитать?
Сделаем небольшое исследование, попробуем просчитать хотя бы приблизительный результат деления.
У каждого числа отбрасываем последние 72 знака.
Тогда у нас остается:
1459141956 / 22248
с такими числами можно оперировать в калькуляторе, что примерно равно: 65585
.
По-этому, мне кажется, что считает вполне правильно.
Дополнено: Если Вас смущает отсутствие дробной части числа, но необходимо ознакомится с правилами деления чисел в C# , особенно этой частью:
When you divide two integers, the result is always an integer.
For example, the result of 7 / 3 is 2.
This is not to be confused with floored division,
as the / operator rounds towards zero: -7 / 3 is -2.
To obtain a quotient as a rational number, use the float, double, or decimal types
То есть, Вам нужно вместо BigInteger
для second
и result
использовать тип с плавающей точкой: float
, double
или же его аналог в библиотеке больших чисел.
Вариант 1. Приведение к типу double
.
BigInteger first = BigInteger.Parse("1459141956031776814097256491377265401586541003894843279763498785157880955654141795");
BigInteger second = BigInteger.Parse("22248470822666314938692568397119675677137950638191323448941735236079264477232");
Console.WriteLine($"Result: {(double)first / (double)second}");
Console.ReadKey();
Да, точность уменьшается, но всё равно остаётся достаточно большой; Вы же не ракету в космос запускаете?..
Вариант 2. Использование BigInteger.DivRem()
.
Метод DivRem()
возвращает остаток от деленя двух BigInteger
, но остаток - это не дробная часть.
BigInteger first = BigInteger.Parse("1459141956031776814097256491377265401586541003894843279763498785157880955654141795");
BigInteger second = BigInteger.Parse("22248470822666314938692568397119675677137950638191323448941735236079264477232");
BigInteger quotient = BigInteger.DivRem(first, second, out BigInteger remainder);
Console.WriteLine($"Result: {quotient}\nRemainder: {remainder}");
Console.ReadKey();
Вариант 3. Использование библиотеки BigRational
.
Numerics.BigRational result = new Numerics.BigRational(first, second);
Я считаю, что первый вариант - наилучшее решение.
Сам с Ruby
не работал, но видел как знакомый на курсах показывал калькулятор с нереально большими числами. Может можно написать .dll на похожем языке и подключить в ваше приложение, но это так, мысли в слух.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Пытаюсь победить ошибку уже 4 день, уже весь интернет облазил, пересмотрел много решений, но так и не приблизился к решению проблемы :(
Каким методом реализовать данную функцию? Если touchcounts, то отслеживает только количество нажатий
Есть форма "form" с несколькими строками, не могу сделать, так, чтобы при нажатии на кнопку submit форма не перезагружалась, а просто записала данные...
Собственно, вопрос