From 38b6bcdc0ca8b0f291bb57dc16227b97d1937105 Mon Sep 17 00:00:00 2001 From: drieseng Date: Mon, 16 May 2016 13:49:56 +0200 Subject: [PATCH] Added tests for BigInteger. In huge parts based on the unit tests in Mono. Update to latest version of BigInteger in Mono before the integration of the MS reference source. Added slashdoc based on MSDN. --- .../Classes/Common/BigIntegerTest.cs | 3329 ++++++++-------- src/Renci.SshNet/Common/BigInteger.cs | 3457 ++++++++++------- 2 files changed, 3698 insertions(+), 3088 deletions(-) diff --git a/src/Renci.SshNet.Tests/Classes/Common/BigIntegerTest.cs b/src/Renci.SshNet.Tests/Classes/Common/BigIntegerTest.cs index 9b890ea6..ea14d7d2 100644 --- a/src/Renci.SshNet.Tests/Classes/Common/BigIntegerTest.cs +++ b/src/Renci.SshNet.Tests/Classes/Common/BigIntegerTest.cs @@ -1,1789 +1,1606 @@ -using Renci.SshNet.Common; -using Microsoft.VisualStudio.TestTools.UnitTesting; +// Based in huge part on: +// +// https://github.com/mono/mono/blob/master/mcs/class/System.Numerics/Test/System.Numerics/BigIntegerTest.cs +// +// Authors: +// Rodrigo Kumpera +// +// Copyright (C) 2010 Novell, Inc (http://www.novell.com) +// + +//#define FEATURE_NUMERICS_BIGINTEGER + using System; +using System.Diagnostics; using System.Globalization; -using Renci.SshNet.Tests.Common; +using System.Threading; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Renci.SshNet.Common; +#if FEATURE_NUMERICS_BIGINTEGER +using BigInteger = System.Numerics.BigInteger; +#else +using BigInteger = Renci.SshNet.Common.BigInteger; +#endif + namespace Renci.SshNet.Tests.Classes.Common { - /// - ///This is a test class for BigIntegerTest and is intended - ///to contain all BigIntegerTest Unit Tests - /// - [TestClass()] - [Ignore] // placeholder for actual test - public class BigIntegerTest : TestBase + [TestClass] + public class BigIntegerTest { - /// - ///A test for BigInteger Constructor - /// - [TestMethod()] - public void BigIntegerConstructorTest() + private static readonly byte[] huge_a = + { + 0x1D, 0x33, 0xFB, 0xFE, 0xB1, 0x2, 0x85, 0x44, 0xCA, 0xDC, 0xFB, 0x70, 0xD, 0x39, + 0xB1, 0x47, 0xB6, 0xE6, 0xA2, 0xD1, 0x19, 0x1E, 0x9F, 0xE4, 0x3C, 0x1E, 0x16, 0x56, 0x13, 0x9C, 0x4D, 0xD3, + 0x5C, 0x74, 0xC9, 0xBD, 0xFA, 0x56, 0x40, 0x58, 0xAC, 0x20, 0x6B, 0x55, 0xA2, 0xD5, 0x41, 0x38, 0xA4, 0x6D, + 0xF6, 0x8C, + }; + + private static readonly byte[] huge_b = + { + 0x96, 0x5, 0xDA, 0xFE, 0x93, 0x17, 0xC1, 0x93, 0xEC, 0x2F, 0x30, 0x2D, 0x8F, + 0x28, 0x13, 0x99, 0x70, 0xF4, 0x4C, 0x60, 0xA6, 0x49, 0x24, 0xF9, 0xB3, 0x4A, 0x41, 0x67, 0xDC, 0xDD, 0xB1, + 0xA5, 0xA6, 0xC0, 0x3D, 0x57, 0x9A, 0xCB, 0x29, 0xE2, 0x94, 0xAC, 0x6C, 0x7D, 0xEF, 0x3E, 0xC6, 0x7A, 0xC1, + 0xA8, 0xC8, 0xB0, 0x20, 0x95, 0xE6, 0x4C, 0xE1, 0xE0, 0x4B, 0x49, 0xD5, 0x5A, 0xB7, + }; + + private static readonly byte[] huge_add = + { + 0xB3, 0x38, 0xD5, 0xFD, 0x45, 0x1A, 0x46, 0xD8, 0xB6, 0xC, 0x2C, 0x9E, 0x9C, + 0x61, 0xC4, 0xE0, 0x26, 0xDB, 0xEF, 0x31, 0xC0, 0x67, 0xC3, 0xDD, 0xF0, 0x68, 0x57, 0xBD, 0xEF, 0x79, 0xFF, + 0x78, 0x3, 0x35, 0x7, 0x15, 0x95, 0x22, 0x6A, 0x3A, 0x41, 0xCD, 0xD7, 0xD2, 0x91, 0x14, 0x8, 0xB3, 0x65, + 0x16, 0xBF, 0x3D, 0x20, 0x95, 0xE6, 0x4C, 0xE1, 0xE0, 0x4B, 0x49, 0xD5, 0x5A, 0xB7, + }; + + private static readonly byte[] a_m_b = + { + 0x87, 0x2D, 0x21, 0x0, 0x1E, 0xEB, 0xC3, 0xB0, 0xDD, 0xAC, 0xCB, 0x43, 0x7E, 0x10, + 0x9E, 0xAE, 0x45, 0xF2, 0x55, 0x71, 0x73, 0xD4, 0x7A, 0xEB, 0x88, 0xD3, 0xD4, 0xEE, 0x36, 0xBE, 0x9B, 0x2D, + 0xB6, 0xB3, 0x8B, 0x66, 0x60, 0x8B, 0x16, 0x76, 0x17, 0x74, 0xFE, 0xD7, 0xB2, 0x96, 0x7B, 0xBD, 0xE2, 0xC4, + 0x2D, 0xDC, 0xDE, 0x6A, 0x19, 0xB3, 0x1E, 0x1F, 0xB4, 0xB6, 0x2A, 0xA5, 0x48, + }; + + private static readonly byte[] b_m_a = + { + 0x79, 0xD2, 0xDE, 0xFF, 0xE1, 0x14, 0x3C, 0x4F, 0x22, 0x53, 0x34, 0xBC, 0x81, + 0xEF, 0x61, 0x51, 0xBA, 0xD, 0xAA, 0x8E, 0x8C, 0x2B, 0x85, 0x14, 0x77, 0x2C, 0x2B, 0x11, 0xC9, 0x41, 0x64, + 0xD2, 0x49, 0x4C, 0x74, 0x99, 0x9F, 0x74, 0xE9, 0x89, 0xE8, 0x8B, 0x1, 0x28, 0x4D, 0x69, 0x84, 0x42, 0x1D, + 0x3B, 0xD2, 0x23, 0x21, 0x95, 0xE6, 0x4C, 0xE1, 0xE0, 0x4B, 0x49, 0xD5, 0x5A, 0xB7, + }; + + private static readonly byte[] huge_mul = + { + 0xFE, 0x83, 0xE1, 0x9B, 0x8D, 0x61, 0x40, 0xD1, 0x60, 0x19, 0xBD, 0x38, 0xF0, + 0xFF, 0x90, 0xAE, 0xDD, 0xAE, 0x73, 0x2C, 0x20, 0x23, 0xCF, 0x6, 0x7A, 0xB4, 0x1C, 0xE7, 0xD9, 0x64, 0x96, + 0x2C, 0x87, 0x7E, 0x1D, 0xB3, 0x8F, 0xD4, 0x33, 0xBA, 0xF4, 0x22, 0xB4, 0xDB, 0xC0, 0x5B, 0xA5, 0x64, 0xA0, + 0xBC, 0xCA, 0x3E, 0x94, 0x95, 0xDA, 0x49, 0xE2, 0xA8, 0x33, 0xA2, 0x6A, 0x33, 0xB1, 0xF2, 0xEA, 0x99, 0x32, + 0xD0, 0xB2, 0xAE, 0x55, 0x75, 0xBD, 0x19, 0xFC, 0x9A, 0xEC, 0x54, 0x87, 0x2A, 0x6, 0xCC, 0x78, 0xDA, 0x88, + 0xBB, 0xAB, 0xA5, 0x47, 0xEF, 0xC7, 0x2B, 0xC7, 0x5B, 0x32, 0x31, 0xCD, 0xD9, 0x53, 0x96, 0x1A, 0x9D, 0x9A, + 0x57, 0x40, 0x51, 0xB6, 0x5D, 0xC, 0x17, 0xD1, 0x86, 0xE9, 0xA4, 0x20, + }; + + private static readonly byte[] huge_div = {0x0,}; + + private static readonly byte[] huge_rem = + { + 0x1D, 0x33, 0xFB, 0xFE, 0xB1, 0x2, 0x85, 0x44, 0xCA, 0xDC, 0xFB, 0x70, 0xD, + 0x39, 0xB1, 0x47, 0xB6, 0xE6, 0xA2, 0xD1, 0x19, 0x1E, 0x9F, 0xE4, 0x3C, 0x1E, 0x16, 0x56, 0x13, 0x9C, 0x4D, + 0xD3, 0x5C, 0x74, 0xC9, 0xBD, 0xFA, 0x56, 0x40, 0x58, 0xAC, 0x20, 0x6B, 0x55, 0xA2, 0xD5, 0x41, 0x38, 0xA4, + 0x6D, 0xF6, 0x8C, + }; + private static readonly byte[][] add_a = {new byte[] {1}, new byte[] {0xFF}, huge_a}; + private static readonly byte[][] add_b = {new byte[] {1}, new byte[] {1}, huge_b}; + private static byte[][] add_c = {new byte[] {2}, new byte[] {0}, huge_add}; + + private readonly NumberFormatInfo _nfi = NumberFormatInfo.InvariantInfo; + private NumberFormatInfo _nfiUser; + + [TestInitialize] + public void SetUpFixture() + { + _nfiUser = new NumberFormatInfo(); + _nfiUser.CurrencyDecimalDigits = 3; + _nfiUser.CurrencyDecimalSeparator = ":"; + _nfiUser.CurrencyGroupSeparator = "/"; + _nfiUser.CurrencyGroupSizes = new[] { 2, 1, 0 }; + _nfiUser.CurrencyNegativePattern = 10; // n $- + _nfiUser.CurrencyPositivePattern = 3; // n $ + _nfiUser.CurrencySymbol = "XYZ"; + _nfiUser.PercentDecimalDigits = 1; + _nfiUser.PercentDecimalSeparator = ";"; + _nfiUser.PercentGroupSeparator = "~"; + _nfiUser.PercentGroupSizes = new[] { 1 }; + _nfiUser.PercentNegativePattern = 2; + _nfiUser.PercentPositivePattern = 2; + _nfiUser.PercentSymbol = "%%%"; + _nfiUser.NumberDecimalSeparator = "."; + } + + [TestMethod] + public void Mul() + { + long[] values = { -1000000000L, -1000, -1, 0, 1, 1000, 100000000L }; + for (var i = 0; i < values.Length; ++i) + { + for (var j = 0; j < values.Length; ++j) + { + var a = new BigInteger(values[i]); + var b = new BigInteger(values[j]); + var c = a * b; + Assert.AreEqual(values[i] * values[j], (long)c, "#_" + i + "_" + j); + } + } + } + + [TestMethod] + public void TestHugeMul() + { + var a = new BigInteger(huge_a); + var b = new BigInteger(huge_b); + Assert.IsTrue(huge_mul.IsEqualTo((a * b).ToByteArray())); + } + + [TestMethod] + public void DivRem() + { + long[] values = { -10000000330L, -5000, -1, 0, 1, 1000, 333, 10234544400L }; + + for (var i = 0; i < values.Length; ++i) + { + for (var j = 0; j < values.Length; ++j) + { + if (values[j] == 0) + continue; + var a = new BigInteger(values[i]); + var b = new BigInteger(values[j]); + BigInteger d; + var c = BigInteger.DivRem(a, b, out d); + + Assert.AreEqual(values[i] / values[j], (long)c, "#a_" + i + "_" + j); + Assert.AreEqual(values[i] % values[j], (long)d, "#b_" + i + "_" + j); + } + } + } + + [TestMethod] + public void TestHugeDivRem() + { + var a = new BigInteger(huge_a); + var b = new BigInteger(huge_b); + BigInteger d; + var c = BigInteger.DivRem(a, b, out d); + + AssertEqual(huge_div, c.ToByteArray()); + AssertEqual(huge_rem, d.ToByteArray()); + } + + [TestMethod] + public void Pow() { - short sign = 0; // TODO: Initialize to an appropriate value - uint[] data = null; // TODO: Initialize to an appropriate value - BigInteger target = new BigInteger(sign, data); - Assert.Inconclusive("TODO: Implement code to verify target"); + try + { + BigInteger.Pow(1, -1); + Assert.Fail("#1"); + } + catch (ArgumentOutOfRangeException) { } + + Assert.AreEqual(1, (int)BigInteger.Pow(99999, 0), "#2"); + Assert.AreEqual(99999, (int)BigInteger.Pow(99999, 1), "#5"); + Assert.AreEqual(59049, (int)BigInteger.Pow(3, 10), "#4"); + Assert.AreEqual(177147, (int)BigInteger.Pow(3, 11), "#5"); + Assert.AreEqual(-177147, (int)BigInteger.Pow(-3, 11), "#6"); } - /// - ///A test for BigInteger Constructor - /// - [TestMethod()] - public void BigIntegerConstructorTest1() + [TestMethod] + public void ModPow() + { + try + { + BigInteger.ModPow(1, -1, 5); + Assert.Fail("#1"); + } + catch (ArgumentOutOfRangeException) { } + try + { + BigInteger.ModPow(1, 5, 0); + Assert.Fail("#2"); + } + catch (DivideByZeroException) { } + + Assert.AreEqual(4L, (long)BigInteger.ModPow(3, 2, 5), "#2"); + Assert.AreEqual(20L, (long)BigInteger.ModPow(555, 10, 71), "#3"); + Assert.AreEqual(20L, (long)BigInteger.ModPow(-555, 10, 71), "#3"); + Assert.AreEqual(-24L, (long)BigInteger.ModPow(-555, 11, 71), "#3"); + } + + [TestMethod] + public void GCD() + { + Assert.AreEqual(999999, (int)BigInteger.GreatestCommonDivisor(999999, 0), "#1"); + Assert.AreEqual(999999, (int)BigInteger.GreatestCommonDivisor(0, 999999), "#2"); + Assert.AreEqual(1, (int)BigInteger.GreatestCommonDivisor(999999, 1), "#3"); + Assert.AreEqual(1, (int)BigInteger.GreatestCommonDivisor(1, 999999), "#4"); + Assert.AreEqual(1, (int)BigInteger.GreatestCommonDivisor(1, 0), "#5"); + Assert.AreEqual(1, (int)BigInteger.GreatestCommonDivisor(0, 1), "#6"); + + Assert.AreEqual(1, (int)BigInteger.GreatestCommonDivisor(999999, -1), "#7"); + Assert.AreEqual(1, (int)BigInteger.GreatestCommonDivisor(-1, 999999), "#8"); + Assert.AreEqual(1, (int)BigInteger.GreatestCommonDivisor(-1, 0), "#9"); + Assert.AreEqual(1, (int)BigInteger.GreatestCommonDivisor(0, -1), "#10"); + + Assert.AreEqual(2, (int)BigInteger.GreatestCommonDivisor(12345678, 8765432), "#11"); + Assert.AreEqual(2, (int)BigInteger.GreatestCommonDivisor(-12345678, 8765432), "#12"); + Assert.AreEqual(2, (int)BigInteger.GreatestCommonDivisor(12345678, -8765432), "#13"); + Assert.AreEqual(2, (int)BigInteger.GreatestCommonDivisor(-12345678, -8765432), "#14"); + + Assert.AreEqual(40, (int)BigInteger.GreatestCommonDivisor(5581 * 40, 6671 * 40), "#15"); + + Assert.AreEqual(5, (int)BigInteger.GreatestCommonDivisor(-5, 0), "#16"); + Assert.AreEqual(5, (int)BigInteger.GreatestCommonDivisor(0, -5), "#17"); + } + + [TestMethod] + public void Log() + { + double delta = 0.000000000000001d; + + Assert.AreEqual(double.NegativeInfinity, BigInteger.Log(0), "#1"); + Assert.AreEqual(0d, BigInteger.Log(1), "#2"); + Assert.AreEqual(double.NaN, BigInteger.Log(-1), "#3"); + Assert.AreEqual(2.3025850929940459d, BigInteger.Log(10), delta, "#4"); + Assert.AreEqual(6.9077552789821368d, BigInteger.Log(1000), delta, "#5"); + Assert.AreEqual(double.NaN, BigInteger.Log(-234), "#6"); + } + + [TestMethod] + public void LogN() + { + var delta = 0.000000000000001d; + + Assert.AreEqual(double.NaN, BigInteger.Log(10, 1), "#1"); + Assert.AreEqual(double.NaN, BigInteger.Log(10, 0), "#2"); + Assert.AreEqual(double.NaN, BigInteger.Log(10, -1), "#3"); + + Assert.AreEqual(double.NaN, BigInteger.Log(10, double.NaN), "#4"); + Assert.AreEqual(double.NaN, BigInteger.Log(10, double.NegativeInfinity), "#5"); + Assert.AreEqual(double.NaN, BigInteger.Log(10, double.PositiveInfinity), "#6"); + + Assert.AreEqual(0d, BigInteger.Log(1, 0), "#7"); + Assert.AreEqual(double.NaN, BigInteger.Log(1, double.NegativeInfinity), "#8"); + Assert.AreEqual(0, BigInteger.Log(1, double.PositiveInfinity), "#9"); + Assert.AreEqual(double.NaN, BigInteger.Log(1, double.NaN), "#10"); + + Assert.AreEqual(-2.5129415947320606d, BigInteger.Log(10, 0.4), delta, "#11"); + } + + [TestMethod] + public void DivRemByZero() + { + try + { + BigInteger d; + BigInteger.DivRem(100, 0, out d); + Assert.Fail("#1"); + } + catch (DivideByZeroException) + { + } + } + + [TestMethod] + public void TestAdd() + { + for (var i = 0; i < add_a.Length; ++i) + { + var a = new BigInteger(add_a[i]); + var b = new BigInteger(add_b[i]); + var c = new BigInteger(add_c[i]); + + Assert.AreEqual(c, a + b, "#" + i + "a"); + Assert.AreEqual(c, b + a, "#" + i + "b"); + Assert.AreEqual(c, BigInteger.Add(a, b), "#" + i + "c"); + AssertEqual(add_c[i], (a + b).ToByteArray()); + } + } + + [TestMethod] + public void TestAdd2() + { + long[] values = { -100000000000L, -1000, -1, 0, 1, 1000, 100000000000L }; + + for (var i = 0; i < values.Length; ++i) + { + for (var j = 0; j < values.Length; ++j) + { + var a = new BigInteger(values[i]); + var b = new BigInteger(values[j]); + var c = a + b; + Assert.AreEqual(values[i] + values[j], (long)c, "#_" + i + "_" + j); + } + } + } + + [TestMethod] + public void TestHugeSub() + { + var a = new BigInteger(huge_a); + var b = new BigInteger(huge_b); + + AssertEqual(a_m_b, (a - b).ToByteArray()); + AssertEqual(b_m_a, (b - a).ToByteArray()); + } + + [TestMethod] + public void TestSub() + { + long[] values = { -100000000000L, -1000, -1, 0, 1, 1000, 100000000000L }; + + for (var i = 0; i < values.Length; ++i) + { + for (var j = 0; j < values.Length; ++j) + { + var a = new BigInteger(values[i]); + var b = new BigInteger(values[j]); + var c = a - b; + var d = BigInteger.Subtract(a, b); + + Assert.AreEqual(values[i] - values[j], (long)c, "#_" + i + "_" + j); + Assert.AreEqual(values[i] - values[j], (long)d, "#_" + i + "_" + j); + } + } + } + + [TestMethod] + public void TestMin() + { + long[] values = { -100000000000L, -1000L, -1L, 0L, 1L, 1000L, 100000000000L }; + + for (var i = 0; i < values.Length; ++i) + { + for (var j = 0; j < values.Length; ++j) + { + var a = new BigInteger(values[i]); + var b = new BigInteger(values[j]); + var c = BigInteger.Min(a, b); + + Assert.AreEqual(Math.Min(values[i], values[j]), (long) c, "#_" + i + "_" + j); + } + } + } + + [TestMethod] + public void TestMax() + { + long[] values = { -100000000000L, -1000, -1, 0, 1, 1000, 100000000000L }; + + for (var i = 0; i < values.Length; ++i) + { + for (var j = 0; j < values.Length; ++j) + { + var a = new BigInteger(values[i]); + var b = new BigInteger(values[j]); + var c = BigInteger.Max(a, b); + + Assert.AreEqual(Math.Max(values[i], values[j]), (long) c, "#_" + i + "_" + j); + } + } + } + + [TestMethod] + public void TestAbs() { - int value = 0; // TODO: Initialize to an appropriate value - BigInteger target = new BigInteger(value); - Assert.Inconclusive("TODO: Implement code to verify target"); + long[] values = { -100000000000L, -1000, -1, 0, 1, 1000, 100000000000L }; + + for (var i = 0; i < values.Length; ++i) + { + var a = new BigInteger(values[i]); + var c = BigInteger.Abs(a); + + Assert.AreEqual(Math.Abs(values[i]), (long) c, "#_" + i); + } } - /// - ///A test for BigInteger Constructor - /// - [TestMethod()] - public void BigIntegerConstructorTest2() + [TestMethod] + public void TestNegate() { - uint value = 0; // TODO: Initialize to an appropriate value - BigInteger target = new BigInteger(value); - Assert.Inconclusive("TODO: Implement code to verify target"); + long[] values = { -100000000000L, -1000, -1, 0, 1, 1000, 100000000000L }; + + for (var i = 0; i < values.Length; ++i) + { + var a = new BigInteger(values[i]); + var c = -a; + var d = BigInteger.Negate(a); + + Assert.AreEqual(-values[i], (long) c, "#_" + i); + Assert.AreEqual(-values[i], (long) d, "#_" + i); + } } - /// - ///A test for BigInteger Constructor - /// - [TestMethod()] - public void BigIntegerConstructorTest3() + [TestMethod] + public void TestInc() { - long value = 0; // TODO: Initialize to an appropriate value - BigInteger target = new BigInteger(value); - Assert.Inconclusive("TODO: Implement code to verify target"); + long[] values = { -100000000000L, -1000, -1, 0, 1, 1000, 100000000000L }; + + for (var i = 0; i < values.Length; ++i) + { + var a = new BigInteger(values[i]); + var b = ++a; + + Assert.AreEqual(++values[i], (long)b, "#_" + i); + } } - /// - ///A test for BigInteger Constructor - /// - [TestMethod()] - public void BigIntegerConstructorTest4() + [TestMethod] + public void TestDec() { - ulong value = 0; // TODO: Initialize to an appropriate value - BigInteger target = new BigInteger(value); - Assert.Inconclusive("TODO: Implement code to verify target"); - } - - /// - ///A test for BigInteger Constructor - /// - [TestMethod()] - public void BigIntegerConstructorTest5() - { - double value = 0F; // TODO: Initialize to an appropriate value - BigInteger target = new BigInteger(value); - Assert.Inconclusive("TODO: Implement code to verify target"); - } - - /// - ///A test for BigInteger Constructor - /// - [TestMethod()] - public void BigIntegerConstructorTest6() - { - float value = 0F; // TODO: Initialize to an appropriate value - BigInteger target = new BigInteger(value); - Assert.Inconclusive("TODO: Implement code to verify target"); - } - - /// - ///A test for BigInteger Constructor - /// - [TestMethod()] - public void BigIntegerConstructorTest7() - { - Decimal value = new Decimal(); // TODO: Initialize to an appropriate value - BigInteger target = new BigInteger(value); - Assert.Inconclusive("TODO: Implement code to verify target"); - } - - /// - ///A test for BigInteger Constructor - /// - [TestMethod()] - public void BigIntegerConstructorTest8() - { - byte[] value = null; // TODO: Initialize to an appropriate value - BigInteger target = new BigInteger(value); - Assert.Inconclusive("TODO: Implement code to verify target"); - } - - /// - ///A test for Abs - /// - [TestMethod()] - public void AbsTest() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = BigInteger.Abs(value); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for Add - /// - [TestMethod()] - public void AddTest() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = BigInteger.Add(left, right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for Compare - /// - [TestMethod()] - public void CompareTest() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - int expected = 0; // TODO: Initialize to an appropriate value - int actual; - actual = BigInteger.Compare(left, right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for CompareTo - /// - [TestMethod()] - public void CompareToTest() - { - BigInteger target = new BigInteger(); // TODO: Initialize to an appropriate value - long other = 0; // TODO: Initialize to an appropriate value - int expected = 0; // TODO: Initialize to an appropriate value - int actual; - actual = target.CompareTo(other); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for CompareTo - /// - [TestMethod()] - public void CompareToTest1() - { - BigInteger target = new BigInteger(); // TODO: Initialize to an appropriate value - ulong other = 0; // TODO: Initialize to an appropriate value - int expected = 0; // TODO: Initialize to an appropriate value - int actual; - actual = target.CompareTo(other); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for CompareTo - /// - [TestMethod()] - public void CompareToTest2() - { - BigInteger target = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger other = new BigInteger(); // TODO: Initialize to an appropriate value - int expected = 0; // TODO: Initialize to an appropriate value - int actual; - actual = target.CompareTo(other); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for CompareTo - /// - [TestMethod()] - public void CompareToTest3() - { - BigInteger target = new BigInteger(); // TODO: Initialize to an appropriate value - object obj = null; // TODO: Initialize to an appropriate value - int expected = 0; // TODO: Initialize to an appropriate value - int actual; - actual = target.CompareTo(obj); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for DivRem - /// - [TestMethod()] - public void DivRemTest() - { - BigInteger dividend = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger divisor = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger remainder = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger remainderExpected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = BigInteger.DivRem(dividend, divisor, out remainder); - Assert.AreEqual(remainderExpected, remainder); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for Divide - /// - [TestMethod()] - public void DivideTest() - { - BigInteger dividend = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger divisor = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = BigInteger.Divide(dividend, divisor); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for Equals - /// - [TestMethod()] - public void EqualsTest() - { - BigInteger target = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger other = new BigInteger(); // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = target.Equals(other); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for Equals - /// - [TestMethod()] - public void EqualsTest1() - { - BigInteger target = new BigInteger(); // TODO: Initialize to an appropriate value - ulong other = 0; // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = target.Equals(other); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for Equals - /// - [TestMethod()] - public void EqualsTest2() - { - BigInteger target = new BigInteger(); // TODO: Initialize to an appropriate value - object obj = null; // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = target.Equals(obj); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for Equals - /// - [TestMethod()] - public void EqualsTest3() - { - BigInteger target = new BigInteger(); // TODO: Initialize to an appropriate value - long other = 0; // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = target.Equals(other); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for GetHashCode - /// - [TestMethod()] - public void GetHashCodeTest() - { - BigInteger target = new BigInteger(); // TODO: Initialize to an appropriate value - int expected = 0; // TODO: Initialize to an appropriate value - int actual; - actual = target.GetHashCode(); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for GreatestCommonDivisor - /// - [TestMethod()] - public void GreatestCommonDivisorTest() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = BigInteger.GreatestCommonDivisor(left, right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for Log - /// - [TestMethod()] - public void LogTest() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - double baseValue = 0F; // TODO: Initialize to an appropriate value - double expected = 0F; // TODO: Initialize to an appropriate value - double actual; - actual = BigInteger.Log(value, baseValue); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for Log - /// - [TestMethod()] - public void LogTest1() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - double expected = 0F; // TODO: Initialize to an appropriate value - double actual; - actual = BigInteger.Log(value); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for Log10 - /// - [TestMethod()] - public void Log10Test() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - double expected = 0F; // TODO: Initialize to an appropriate value - double actual; - actual = BigInteger.Log10(value); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for Max - /// - [TestMethod()] - public void MaxTest() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = BigInteger.Max(left, right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for Min - /// - [TestMethod()] - public void MinTest() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = BigInteger.Min(left, right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for ModInverse - /// - [TestMethod()] - public void ModInverseTest() - { - BigInteger bi = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger modulus = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = BigInteger.ModInverse(bi, modulus); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for ModPow - /// - [TestMethod()] - public void ModPowTest() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger exponent = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger modulus = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = BigInteger.ModPow(value, exponent, modulus); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for Multiply - /// - [TestMethod()] - public void MultiplyTest() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = BigInteger.Multiply(left, right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for Negate - /// - [TestMethod()] - public void NegateTest() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = BigInteger.Negate(value); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for Parse - /// - [TestMethod()] - public void ParseTest() - { - string value = string.Empty; // TODO: Initialize to an appropriate value - IFormatProvider provider = null; // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = BigInteger.Parse(value, provider); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for Parse - /// - [TestMethod()] - public void ParseTest1() - { - string value = string.Empty; // TODO: Initialize to an appropriate value - NumberStyles style = new NumberStyles(); // TODO: Initialize to an appropriate value - IFormatProvider provider = null; // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = BigInteger.Parse(value, style, provider); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for Parse - /// - [TestMethod()] - public void ParseTest2() - { - string value = string.Empty; // TODO: Initialize to an appropriate value - NumberStyles style = new NumberStyles(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = BigInteger.Parse(value, style); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for PositiveMod - /// - [TestMethod()] - public void PositiveModTest() - { - BigInteger dividend = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger divisor = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = BigInteger.PositiveMod(dividend, divisor); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for Pow - /// - [TestMethod()] - public void PowTest() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - int exponent = 0; // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = BigInteger.Pow(value, exponent); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for Random - /// - [TestMethod()] - public void RandomTest() - { - int bitLength = 0; // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = BigInteger.Random(bitLength); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for Remainder - /// - [TestMethod()] - public void RemainderTest() - { - BigInteger dividend = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger divisor = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = BigInteger.Remainder(dividend, divisor); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for Subtract - /// - [TestMethod()] - public void SubtractTest() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = BigInteger.Subtract(left, right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for ToByteArray - /// - [TestMethod()] - public void ToByteArrayTest() - { - BigInteger target = new BigInteger(); // TODO: Initialize to an appropriate value - byte[] expected = null; // TODO: Initialize to an appropriate value - byte[] actual; - actual = target.ToByteArray(); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for ToString - /// - [TestMethod()] - public void ToStringTest() - { - BigInteger target = new BigInteger(); // TODO: Initialize to an appropriate value - string format = string.Empty; // TODO: Initialize to an appropriate value - IFormatProvider provider = null; // TODO: Initialize to an appropriate value - string expected = string.Empty; // TODO: Initialize to an appropriate value - string actual; - actual = target.ToString(format, provider); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for ToString - /// - [TestMethod()] - public void ToStringTest1() - { - BigInteger target = new BigInteger(); // TODO: Initialize to an appropriate value - string format = string.Empty; // TODO: Initialize to an appropriate value - string expected = string.Empty; // TODO: Initialize to an appropriate value - string actual; - actual = target.ToString(format); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for ToString - /// - [TestMethod()] - public void ToStringTest2() - { - BigInteger target = new BigInteger(); // TODO: Initialize to an appropriate value - IFormatProvider provider = null; // TODO: Initialize to an appropriate value - string expected = string.Empty; // TODO: Initialize to an appropriate value - string actual; - actual = target.ToString(provider); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for ToString - /// - [TestMethod()] - public void ToStringTest3() - { - BigInteger target = new BigInteger(); // TODO: Initialize to an appropriate value - string expected = string.Empty; // TODO: Initialize to an appropriate value - string actual; - actual = target.ToString(); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for TryParse - /// - [TestMethod()] - public void TryParseTest() - { - string value = string.Empty; // TODO: Initialize to an appropriate value - NumberStyles style = new NumberStyles(); // TODO: Initialize to an appropriate value - CultureInfo cultureInfo = null; // TODO: Initialize to an appropriate value - BigInteger result = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger resultExpected = new BigInteger(); // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = BigInteger.TryParse(value, style, cultureInfo, out result); - Assert.AreEqual(resultExpected, result); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for TryParse - /// - [TestMethod()] - public void TryParseTest1() - { - string value = string.Empty; // TODO: Initialize to an appropriate value - BigInteger result = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger resultExpected = new BigInteger(); // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = BigInteger.TryParse(value, out result); - Assert.AreEqual(resultExpected, result); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Addition - /// - [TestMethod()] - public void op_AdditionTest() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = (left + right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_BitwiseAnd - /// - [TestMethod()] - public void op_BitwiseAndTest() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = (left & right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_BitwiseOr - /// - [TestMethod()] - public void op_BitwiseOrTest() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = (left | right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Decrement - /// - [TestMethod()] - public void op_DecrementTest() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = --(value); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Division - /// - [TestMethod()] - public void op_DivisionTest() - { - BigInteger dividend = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger divisor = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = (dividend / divisor); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Equality - /// - [TestMethod()] - public void op_EqualityTest() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left == right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Equality - /// - [TestMethod()] - public void op_EqualityTest1() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - long right = 0; // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left == right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Equality - /// - [TestMethod()] - public void op_EqualityTest2() - { - long left = 0; // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left == right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Equality - /// - [TestMethod()] - public void op_EqualityTest3() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - ulong right = 0; // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left == right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Equality - /// - [TestMethod()] - public void op_EqualityTest4() - { - ulong left = 0; // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left == right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_ExclusiveOr - /// - [TestMethod()] - public void op_ExclusiveOrTest() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = (left ^ right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Explicit - /// - [TestMethod()] - public void op_ExplicitTest() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - short expected = 0; // TODO: Initialize to an appropriate value - short actual; - actual = ((short)(value)); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Explicit - /// - [TestMethod()] - public void op_ExplicitTest1() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - ushort expected = 0; // TODO: Initialize to an appropriate value - ushort actual; - actual = ((ushort)(value)); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Explicit - /// - [TestMethod()] - public void op_ExplicitTest2() - { - Decimal value = new Decimal(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = ((BigInteger)(value)); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Explicit - /// - [TestMethod()] - public void op_ExplicitTest3() - { - float value = 0F; // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = ((BigInteger)(value)); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Explicit - /// - [TestMethod()] - public void op_ExplicitTest4() - { - double value = 0F; // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = ((BigInteger)(value)); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Explicit - /// - [TestMethod()] - public void op_ExplicitTest5() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - Decimal expected = new Decimal(); // TODO: Initialize to an appropriate value - Decimal actual; - actual = ((Decimal)(value)); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Explicit - /// - [TestMethod()] - public void op_ExplicitTest6() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - float expected = 0F; // TODO: Initialize to an appropriate value - float actual; - actual = ((float)(value)); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Explicit - /// - [TestMethod()] - public void op_ExplicitTest7() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - double expected = 0F; // TODO: Initialize to an appropriate value - double actual; - actual = ((double)(value)); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Explicit - /// - [TestMethod()] - public void op_ExplicitTest8() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - ulong expected = 0; // TODO: Initialize to an appropriate value - ulong actual; - actual = ((ulong)(value)); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Explicit - /// - [TestMethod()] - public void op_ExplicitTest9() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - long expected = 0; // TODO: Initialize to an appropriate value - long actual; - actual = ((long)(value)); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Explicit - /// - [TestMethod()] - public void op_ExplicitTest10() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - sbyte expected = 0; // TODO: Initialize to an appropriate value - sbyte actual; - actual = ((sbyte)(value)); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Explicit - /// - [TestMethod()] - public void op_ExplicitTest11() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - byte expected = 0; // TODO: Initialize to an appropriate value - byte actual; - actual = ((byte)(value)); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Explicit - /// - [TestMethod()] - public void op_ExplicitTest12() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - int expected = 0; // TODO: Initialize to an appropriate value - int actual; - actual = ((int)(value)); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Explicit - /// - [TestMethod()] - public void op_ExplicitTest13() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - uint expected = 0; // TODO: Initialize to an appropriate value - uint actual; - actual = ((uint)(value)); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_GreaterThan - /// - [TestMethod()] - public void op_GreaterThanTest() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - long right = 0; // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left > right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_GreaterThan - /// - [TestMethod()] - public void op_GreaterThanTest1() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - ulong right = 0; // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left > right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_GreaterThan - /// - [TestMethod()] - public void op_GreaterThanTest2() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left > right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_GreaterThan - /// - [TestMethod()] - public void op_GreaterThanTest3() - { - long left = 0; // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left > right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_GreaterThan - /// - [TestMethod()] - public void op_GreaterThanTest4() - { - ulong left = 0; // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left > right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_GreaterThanOrEqual - /// - [TestMethod()] - public void op_GreaterThanOrEqualTest() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left >= right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_GreaterThanOrEqual - /// - [TestMethod()] - public void op_GreaterThanOrEqualTest1() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - long right = 0; // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left >= right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_GreaterThanOrEqual - /// - [TestMethod()] - public void op_GreaterThanOrEqualTest2() - { - long left = 0; // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left >= right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_GreaterThanOrEqual - /// - [TestMethod()] - public void op_GreaterThanOrEqualTest3() - { - ulong left = 0; // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left >= right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_GreaterThanOrEqual - /// - [TestMethod()] - public void op_GreaterThanOrEqualTest4() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - ulong right = 0; // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left >= right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Implicit - /// - [TestMethod()] - public void op_ImplicitTest() - { - short value = 0; // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = value; - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Implicit - /// - [TestMethod()] - public void op_ImplicitTest1() - { - uint value = 0; // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = value; - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Implicit - /// - [TestMethod()] - public void op_ImplicitTest2() - { - int value = 0; // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = value; - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Implicit - /// - [TestMethod()] - public void op_ImplicitTest3() - { - ushort value = 0; // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = value; - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Implicit - /// - [TestMethod()] - public void op_ImplicitTest4() - { - byte value = 0; // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = value; - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Implicit - /// - [TestMethod()] - public void op_ImplicitTest5() - { - sbyte value = 0; // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = value; - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Implicit - /// - [TestMethod()] - public void op_ImplicitTest6() - { - long value = 0; // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = value; - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Implicit - /// - [TestMethod()] - public void op_ImplicitTest7() - { - ulong value = 0; // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = value; - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Increment - /// - [TestMethod()] - public void op_IncrementTest() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = ++(value); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Inequality - /// - [TestMethod()] - public void op_InequalityTest() - { - long left = 0; // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left != right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Inequality - /// - [TestMethod()] - public void op_InequalityTest1() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - ulong right = 0; // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left != right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Inequality - /// - [TestMethod()] - public void op_InequalityTest2() - { - ulong left = 0; // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left != right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Inequality - /// - [TestMethod()] - public void op_InequalityTest3() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - long right = 0; // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left != right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Inequality - /// - [TestMethod()] - public void op_InequalityTest4() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left != right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_LeftShift - /// - [TestMethod()] - public void op_LeftShiftTest() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - int shift = 0; // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = (value << shift); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_LessThan - /// - [TestMethod()] - public void op_LessThanTest() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - ulong right = 0; // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left < right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_LessThan - /// - [TestMethod()] - public void op_LessThanTest1() - { - long left = 0; // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left < right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_LessThan - /// - [TestMethod()] - public void op_LessThanTest2() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - long right = 0; // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left < right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_LessThan - /// - [TestMethod()] - public void op_LessThanTest3() - { - ulong left = 0; // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left < right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_LessThan - /// - [TestMethod()] - public void op_LessThanTest4() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left < right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_LessThanOrEqual - /// - [TestMethod()] - public void op_LessThanOrEqualTest() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left <= right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_LessThanOrEqual - /// - [TestMethod()] - public void op_LessThanOrEqualTest1() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - long right = 0; // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left <= right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_LessThanOrEqual - /// - [TestMethod()] - public void op_LessThanOrEqualTest2() - { - long left = 0; // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left <= right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_LessThanOrEqual - /// - [TestMethod()] - public void op_LessThanOrEqualTest3() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - ulong right = 0; // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left <= right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_LessThanOrEqual - /// - [TestMethod()] - public void op_LessThanOrEqualTest4() - { - ulong left = 0; // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - bool expected = false; // TODO: Initialize to an appropriate value - bool actual; - actual = (left <= right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Modulus - /// - [TestMethod()] - public void op_ModulusTest() - { - BigInteger dividend = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger divisor = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = (dividend % divisor); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Multiply - /// - [TestMethod()] - public void op_MultiplyTest() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = (left * right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_OnesComplement - /// - [TestMethod()] - public void op_OnesComplementTest() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = ~(value); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_RightShift - /// - [TestMethod()] - public void op_RightShiftTest() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - int shift = 0; // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = (value >> shift); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_Subtraction - /// - [TestMethod()] - public void op_SubtractionTest() - { - BigInteger left = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger right = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = (left - right); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_UnaryNegation - /// - [TestMethod()] - public void op_UnaryNegationTest() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = -(value); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for op_UnaryPlus - /// - [TestMethod()] - public void op_UnaryPlusTest() - { - BigInteger value = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger expected = new BigInteger(); // TODO: Initialize to an appropriate value - BigInteger actual; - actual = +(value); - Assert.AreEqual(expected, actual); - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for BitLength - /// - [TestMethod()] - public void BitLengthTest() - { - BigInteger target = new BigInteger(); // TODO: Initialize to an appropriate value - int actual; - actual = target.BitLength; - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for IsEven - /// - [TestMethod()] - public void IsEvenTest() - { - BigInteger target = new BigInteger(); // TODO: Initialize to an appropriate value - bool actual; - actual = target.IsEven; - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for IsOne - /// - [TestMethod()] - public void IsOneTest() - { - BigInteger target = new BigInteger(); // TODO: Initialize to an appropriate value - bool actual; - actual = target.IsOne; - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for IsPowerOfTwo - /// - [TestMethod()] - public void IsPowerOfTwoTest() - { - BigInteger target = new BigInteger(); // TODO: Initialize to an appropriate value - bool actual; - actual = target.IsPowerOfTwo; - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for IsZero - /// - [TestMethod()] - public void IsZeroTest() + long[] values = { -100000000000L, -1000, -1, 0, 1, 1000, 100000000000L }; + + for (var i = 0; i < values.Length; ++i) + { + var a = new BigInteger(values[i]); + var b = --a; + + Assert.AreEqual(--values[i], (long) b, "#_" + i); + } + } + + [TestMethod] + public void TestBitwiseOps() { - BigInteger target = new BigInteger(); // TODO: Initialize to an appropriate value - bool actual; - actual = target.IsZero; - Assert.Inconclusive("Verify the correctness of this test method."); - } - - /// - ///A test for MinusOne - /// - [TestMethod()] - public void MinusOneTest() + long[] values = { -100000000000L, -1000, -1, 0, 1, 1000, 100000000000L, 0xFFFF00000000L }; + + for (var i = 0; i < values.Length; ++i) + { + for (var j = 0; j < values.Length; ++j) + { + var a = new BigInteger(values[i]); + var b = new BigInteger(values[j]); + + Assert.AreEqual(values[i] | values[j], (long) (a | b), "#b_" + i + "_" + j); + Assert.AreEqual(values[i] & values[j], (long) (a & b), "#a_" + i + "_" + j); + Assert.AreEqual(values[i] ^ values[j], (long) (a ^ b), "#c_" + i + "_" + j); + Assert.AreEqual(~values[i], (long) ~a, "#d_" + i + "_" + j); + } + } + } + + [TestMethod] + public void TestLeftShift() { - BigInteger actual; - actual = BigInteger.MinusOne; - Assert.Inconclusive("Verify the correctness of this test method."); + AssertEqual(new byte[] { 0x00, 0x28 }, (new BigInteger(0x0A) << 10).ToByteArray()); + AssertEqual(new byte[] { 0x00, 0xD8 }, (new BigInteger(-10) << 10).ToByteArray()); + AssertEqual(new byte[] { 0x00, 0x00, 0xFF }, (new BigInteger(-1) << 16).ToByteArray()); + AssertEqual(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A }, (new BigInteger(0x0A) << 80).ToByteArray()); + AssertEqual(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF6 }, (new BigInteger(-10) << 80).ToByteArray()); + AssertEqual(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF }, (new BigInteger(-1) << 80).ToByteArray()); + AssertEqual(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xD9 }, (new BigInteger(-1234) << 75).ToByteArray()); + AssertEqual(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x91, 0x00 }, (new BigInteger(0x1234) << 75).ToByteArray()); + AssertEqual(new byte[] { 0xFF, 0x00 }, (new BigInteger(0xFF00) << -8).ToByteArray()); } - /// - ///A test for One - /// - [TestMethod()] - public void OneTest() + [TestMethod] + public void TestRightShift() { - BigInteger actual; - actual = BigInteger.One; - Assert.Inconclusive("Verify the correctness of this test method."); + AssertEqual(new byte[] { 0x16, 0xB0, 0x4C, 0x02 }, (new BigInteger(1234567899L) >> 5).ToByteArray()); + AssertEqual(new byte[] { 0x2C, 0x93, 0x00 }, (new BigInteger(1234567899L) >> 15).ToByteArray()); + AssertEqual(new byte[] { 0xFF, 0xFF, 0x7F }, (new BigInteger(long.MaxValue - 100) >> 40).ToByteArray()); + AssertEqual(new byte[] { 0xE9, 0x4F, 0xB3, 0xFD }, (new BigInteger(-1234567899L) >> 5).ToByteArray()); + AssertEqual(new byte[] { 0xD3, 0x6C, 0xFF }, (new BigInteger(-1234567899L) >> 15).ToByteArray()); + AssertEqual(new byte[] { 0x00, 0x00, 0x80 }, (new BigInteger(long.MinValue + 100) >> 40).ToByteArray()); + AssertEqual(new byte[] { 0xFF }, (new BigInteger(-1234567899L) >> 90).ToByteArray()); + AssertEqual(new byte[] { 0x00 }, (new BigInteger(999999) >> 90).ToByteArray()); + AssertEqual(new byte[] { 0x00, 0x00, 0xFF, 0x00 }, (new BigInteger(0xFF00) >> -8).ToByteArray()); } - /// - ///A test for Sign - /// - [TestMethod()] - public void SignTest() + [TestMethod] + public void CompareOps() { - BigInteger target = new BigInteger(); // TODO: Initialize to an appropriate value - int actual; - actual = target.Sign; - Assert.Inconclusive("Verify the correctness of this test method."); + long[] values = { -100000000000L, -1000, -1, 0, 1, 1000, 100000000000L }; + + for (var i = 0; i < values.Length; ++i) + { + for (var j = 0; j < values.Length; ++j) + { + var a = new BigInteger(values[i]); + var b = new BigInteger(values[j]); + + Assert.AreEqual(values[i].CompareTo(values[j]), a.CompareTo(b), "#a_" + i + "_" + j); + Assert.AreEqual(values[i].CompareTo(values[j]), BigInteger.Compare(a, b), "#b_" + i + "_" + j); + + Assert.AreEqual(values[i] < values[j], a < b, "#c_" + i + "_" + j); + Assert.AreEqual(values[i] <= values[j], a <= b, "#d_" + i + "_" + j); + Assert.AreEqual(values[i] == values[j], a == b, "#e_" + i + "_" + j); + Assert.AreEqual(values[i] != values[j], a != b, "#f_" + i + "_" + j); + Assert.AreEqual(values[i] >= values[j], a >= b, "#g_" + i + "_" + j); + Assert.AreEqual(values[i] > values[j], a > b, "#h_" + i + "_" + j); + } + } } - /// - ///A test for Zero - /// - [TestMethod()] - public void ZeroTest() + [TestMethod] + public void CompareOps2() { - BigInteger actual; - actual = BigInteger.Zero; - Assert.Inconclusive("Verify the correctness of this test method."); + BigInteger a = new BigInteger(100000000000L); + BigInteger b = new BigInteger(28282828282UL); + + Assert.IsTrue(a >= b, "#1"); + Assert.IsTrue(a >= b, "#2"); + Assert.IsFalse(a < b, "#3"); + Assert.IsFalse(a <= b, "#4"); + Assert.AreEqual(1, a.CompareTo(b), "#5"); } + + [TestMethod] + public void CompareULong() + { + long[] values = { -100000000000L, -1000, -1, 0, 1, 1000, 100000000000L, 0xAA00000000L }; + ulong[] uvalues = { 0, 1, 1000, 100000000000L, 999999, 28282828282, 0xAA00000000, ulong.MaxValue }; + + for (var i = 0; i < values.Length; ++i) + { + for (var j = 0; j < uvalues.Length; ++j) + { + var a = new BigInteger(values[i]); + var b = uvalues[j]; + var c = new BigInteger(b); + + Assert.AreEqual(a.CompareTo(c), a.CompareTo(b), "#a_" + i + "_" + j); + + Assert.AreEqual(a > c, a > b, "#b_" + i + "_" + j); + Assert.AreEqual(a < c, a < b, "#c_" + i + "_" + j); + Assert.AreEqual(a <= c, a <= b, "#d_" + i + "_" + j); + Assert.AreEqual(a == c, a == b, "#e_" + i + "_" + j); + Assert.AreEqual(a != c, a != b, "#f_" + i + "_" + j); + Assert.AreEqual(a >= c, a >= b, "#g_" + i + "_" + j); + + Assert.AreEqual(c > a, b > a, "#ib_" + i + "_" + j); + Assert.AreEqual(c < a, b < a, "#ic_" + i + "_" + j); + Assert.AreEqual(c <= a, b <= a, "#id_" + i + "_" + j); + Assert.AreEqual(c == a, b == a, "#ie_" + i + "_" + j); + Assert.AreEqual(c != a, b != a, "#if_" + i + "_" + j); + Assert.AreEqual(c >= a, b >= a, "#ig_" + i + "_" + j); + } + } + } + + [TestMethod] + public void CompareLong() + { + long[] values = { -100000000000L, -1000, -1, 0, 1, 1000, 9999999, 100000000000L, 0xAA00000000, long.MaxValue, long.MinValue }; + + for (int i = 0; i < values.Length; ++i) + { + for (int j = 0; j < values.Length; ++j) + { + var a = new BigInteger(values[i]); + var b = values[j]; + var c = new BigInteger(b); + + Assert.AreEqual(a.CompareTo(c), a.CompareTo(b), "#a_" + i + "_" + j); + + Assert.AreEqual(a > c, a > b, "#b_" + i + "_" + j); + Assert.AreEqual(a < c, a < b, "#c_" + i + "_" + j); + Assert.AreEqual(a <= c, a <= b, "#d_" + i + "_" + j); + Assert.AreEqual(a == c, a == b, "#e_" + i + "_" + j); + Assert.AreEqual(a != c, a != b, "#f_" + i + "_" + j); + Assert.AreEqual(a >= c, a >= b, "#g_" + i + "_" + j); + + Assert.AreEqual(c > a, b > a, "#ib_" + i + "_" + j); + Assert.AreEqual(c < a, b < a, "#ic_" + i + "_" + j); + Assert.AreEqual(c <= a, b <= a, "#id_" + i + "_" + j); + Assert.AreEqual(c == a, b == a, "#ie_" + i + "_" + j); + Assert.AreEqual(c != a, b != a, "#if_" + i + "_" + j); + Assert.AreEqual(c >= a, b >= a, "#ig_" + i + "_" + j); + } + } + } + + [TestMethod] + public void TestEquals() + { + var a = new BigInteger(10); + var b = new BigInteger(10); + var c = new BigInteger(-10); + + Assert.AreEqual(a, b, "#1"); + Assert.AreNotEqual(a, c, "#2"); + Assert.AreEqual(a, 10, "#3"); + } + + [TestMethod] + public void Ctor_ByteArray_ShouldThrowArgumentNullExceptionWhenValueIsNull() + { + const byte[] value = null; + + try + { + var actual = new BigInteger(value); + Assert.Fail("#1:" + actual); + } + catch (ArgumentNullException ex) + { + Assert.IsNull(ex.InnerException); + Assert.AreEqual("value", ex.ParamName); + } + } + + [TestMethod] + public void ByteArrayCtor() + { + Assert.AreEqual(0, (int) new BigInteger(new byte[0])); + Assert.AreEqual(0, (int) new BigInteger(new byte[1])); + Assert.AreEqual(0, (int) new BigInteger(new byte[2])); + } + + [TestMethod] + public void IntCtorRoundTrip() + { + int[] values = + { + int.MinValue, -0x2F33BB, -0x1F33, -0x33, 0, 0x33, + 0x80, 0x8190, 0xFF0011, 0x1234, 0x11BB99, 0x44BB22CC, + int.MaxValue + }; + + foreach (var val in values) + { + var a = new BigInteger(val); + var b = new BigInteger(a.ToByteArray()); + + Assert.AreEqual(val, (int)a, "#a_" + val); + Assert.AreEqual(val, (int)b, "#b_" + val); + } + } + + [TestMethod] + public void LongCtorRoundTrip() + { + var z = -1L + int.MinValue; + + var za = new BigInteger(z); + var zb = za.ToByteArray(); + var zc = new BigInteger(zb); + + bool equal = za.Equals(zc); + + + long[] values = + { + 0L, long.MinValue, long.MaxValue, -1, 1L + int.MaxValue, -1L + int.MinValue, 0x1234, 0xFFFFFFFFL, + 0x1FFFFFFFFL, -0xFFFFFFFFL, -0x1FFFFFFFFL, 0x100000000L, -0x100000000L, 0x100000001L, -0x100000001L, + 4294967295L, -4294967295L, 4294967296L, -4294967296L + }; + + foreach (var val in values) + { + try + { + var a = new BigInteger(val); + var b = new BigInteger(a.ToByteArray()); + + Assert.AreEqual(val, (long)a, "#a_" + val); + Assert.AreEqual(val, (long)b, "#b_" + val); + Assert.AreEqual(a, b, "#a == #b (" + val + ")"); + } + catch (Exception e) + { + Assert.Fail("Failed to roundtrip {0}: {1}", val, e); + } + } + } + + [TestMethod] + public void ByteArrayCtorRoundTrip() + { + var arr = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + AssertEqual(arr, new BigInteger(arr).ToByteArray()); + + arr = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 0xFF, 0x0 }; + AssertEqual(arr, new BigInteger(arr).ToByteArray()); + + arr = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xF0 }; + AssertEqual(arr, new BigInteger(arr).ToByteArray()); + + arr = new byte[] { 1 }; + AssertEqual(arr, new BigInteger(arr).ToByteArray()); + + arr = new byte[] { 1, 2 }; + AssertEqual(arr, new BigInteger(arr).ToByteArray()); + + arr = new byte[] { 1, 2, 3 }; + AssertEqual(arr, new BigInteger(arr).ToByteArray()); + + arr = new byte[] { 1, 2, 3, 4 }; + AssertEqual(arr, new BigInteger(arr).ToByteArray()); + + arr = new byte[] { 1, 2, 3, 4, 5 }; + AssertEqual(arr, new BigInteger(arr).ToByteArray()); + + arr = new byte[] { 1, 2, 3, 4, 5, 6 }; + AssertEqual(arr, new BigInteger(arr).ToByteArray()); + + arr = new byte[] { 1, 2, 3, 4, 5, 6, 7 }; + AssertEqual(arr, new BigInteger(arr).ToByteArray()); + + arr = new byte[] { 1, 2, 3, 4, 5 }; + AssertEqual(arr, new BigInteger(arr).ToByteArray()); + + arr = new byte[] { 0 }; + AssertEqual(arr, new BigInteger(arr).ToByteArray()); + + arr = new byte[] { 0xFF, 00 }; + AssertEqual(arr, new BigInteger(arr).ToByteArray()); + + arr = new byte[] { 1, 0, 0, 0, 0, 0, }; + AssertEqual(new byte[] { 1 }, new BigInteger(arr).ToByteArray()); + } + + [TestMethod] + public void TestIntCtorProperties() + { + BigInteger a = new BigInteger(10); + Assert.IsTrue(a.IsEven, "#1"); + Assert.IsFalse(a.IsOne, "#2"); + Assert.IsFalse(a.IsPowerOfTwo, "#3"); + Assert.IsFalse(a.IsZero, "#4"); + Assert.AreEqual(1, a.Sign, "#5"); + + Assert.IsFalse(new BigInteger(11).IsEven, "#6"); + Assert.IsTrue(new BigInteger(1).IsOne, "#7"); + Assert.IsTrue(new BigInteger(32).IsPowerOfTwo, "#8"); + Assert.IsTrue(new BigInteger(0).IsZero, "#9"); + Assert.IsTrue(new BigInteger().IsZero, "#9b"); + Assert.AreEqual(0, new BigInteger(0).Sign, "#10"); + Assert.AreEqual(-1, new BigInteger(-99999).Sign, "#11"); + + Assert.IsFalse(new BigInteger(0).IsPowerOfTwo, "#12"); + Assert.IsFalse(new BigInteger().IsPowerOfTwo, "#12b"); + Assert.IsFalse(new BigInteger(-16).IsPowerOfTwo, "#13"); + Assert.IsTrue(new BigInteger(1).IsPowerOfTwo, "#14"); + } + + [TestMethod] + public void TestIntCtorToString() + { + Assert.AreEqual("5555", new BigInteger(5555).ToString(), "#1"); + Assert.AreEqual("-99999", new BigInteger(-99999).ToString(), "#2"); + } + + [TestMethod] + public void TestToStringFmt() + { + Assert.AreEqual("123456789123456", new BigInteger(123456789123456).ToString("D2"), "#1"); + Assert.AreEqual("0000000005", new BigInteger(5).ToString("d10"), "#2"); + Assert.AreEqual("0A8", new BigInteger(168).ToString("X"), "#3"); + Assert.AreEqual("0", new BigInteger(0).ToString("X"), "#4"); + Assert.AreEqual("0", new BigInteger().ToString("X"), "#4b"); + Assert.AreEqual("1", new BigInteger(1).ToString("X"), "#5"); + Assert.AreEqual("0A", new BigInteger(10).ToString("X"), "#6"); + Assert.AreEqual("F6", new BigInteger(-10).ToString("X"), "#7"); + + Assert.AreEqual("10000000000000000000000000000000000000000000000000000000", BigInteger.Pow(10, 55).ToString("G"), "#8"); + + Assert.AreEqual("10000000000000000000000000000000000000000000000000000000", BigInteger.Pow(10, 55).ToString("R"), "#9"); + + + Assert.AreEqual("000000000A", new BigInteger(10).ToString("X10"), "#10"); + Assert.AreEqual("0000000010", new BigInteger(10).ToString("G10"), "#11"); + } + + [TestMethod] + public void TestToStringFmtProvider() + { + NumberFormatInfo info = new NumberFormatInfo + { + NegativeSign = ">", + PositiveSign = "%" + }; + + Assert.AreEqual("10", new BigInteger(10).ToString(info), "#1"); + Assert.AreEqual(">10", new BigInteger(-10).ToString(info), "#2"); + Assert.AreEqual("0A", new BigInteger(10).ToString("X", info), "#3"); + Assert.AreEqual("F6", new BigInteger(-10).ToString("X", info), "#4"); + Assert.AreEqual("10", new BigInteger(10).ToString("G", info), "#5"); + Assert.AreEqual(">10", new BigInteger(-10).ToString("G", info), "#6"); + Assert.AreEqual("10", new BigInteger(10).ToString("D", info), "#7"); + Assert.AreEqual(">10", new BigInteger(-10).ToString("D", info), "#8"); + Assert.AreEqual("10", new BigInteger(10).ToString("R", info), "#9"); + Assert.AreEqual(">10", new BigInteger(-10).ToString("R", info), "#10"); + + info = new NumberFormatInfo(); + info.NegativeSign = "#$%"; + Assert.AreEqual("#$%10", new BigInteger(-10).ToString(info), "#2"); + Assert.AreEqual("#$%10", new BigInteger(-10).ToString(null, info), "#2"); + + info = new NumberFormatInfo(); + Assert.AreEqual("-10", new BigInteger(-10).ToString(info), "#2"); + + } + + [TestMethod] + public void TestToIntOperator() + { + try + { + int v = (int)new BigInteger(huge_a); + Assert.Fail("#1"); + } + catch (OverflowException) { } + + try + { + int v = (int)new BigInteger(1L + int.MaxValue); + Assert.Fail("#2"); + } + catch (OverflowException) { } + + try + { + int v = (int)new BigInteger(-1L + int.MinValue); + Assert.Fail("#3"); + } + catch (OverflowException) { } + + Assert.AreEqual(int.MaxValue, (int)new BigInteger(int.MaxValue), "#4"); + Assert.AreEqual(int.MinValue, (int)new BigInteger(int.MinValue), "#5"); + } + + + [TestMethod] + public void TestToLongOperator() + { + try + { + long v = (long)new BigInteger(huge_a); + Assert.Fail("#1"); + } + catch (OverflowException) { } + + //long.MaxValue + 1 + try + { + long v = (long)new BigInteger(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 }); + Assert.Fail("#2"); + } + catch (OverflowException) { } + + //TODO long.MinValue - 1 + try + { + long v = (long)new BigInteger(new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF }); + Assert.Fail("#3"); + } + catch (OverflowException) { } + + Assert.AreEqual(long.MaxValue, (long)new BigInteger(long.MaxValue), "#4"); + Assert.AreEqual(long.MinValue, (long)new BigInteger(long.MinValue), "#5"); + } + + [TestMethod] + public void TestIntCtorToByteArray() + { + AssertEqual(new byte[] { 0xFF }, new BigInteger(-1).ToByteArray()); + AssertEqual(new byte[] { 0xD4, 0xFE }, new BigInteger(-300).ToByteArray()); + AssertEqual(new byte[] { 0x80, 0x00 }, new BigInteger(128).ToByteArray()); + AssertEqual(new byte[] { 0x00, 0x60 }, new BigInteger(0x6000).ToByteArray()); + AssertEqual(new byte[] { 0x00, 0x80, 0x00 }, new BigInteger(0x8000).ToByteArray()); + AssertEqual(new byte[] { 0xDD, 0xBC, 0x00, 0x7A }, new BigInteger(0x7A00BCDD).ToByteArray()); + AssertEqual(new byte[] { 0xFF, 0xFF, 0xFF, 0x7F }, new BigInteger(int.MaxValue).ToByteArray()); + AssertEqual(new byte[] { 0x00, 0x00, 0x00, 0x80 }, new BigInteger(int.MinValue).ToByteArray()); + AssertEqual(new byte[] { 0x01, 0x00, 0x00, 0x80 }, new BigInteger(int.MinValue + 1).ToByteArray()); + AssertEqual(new byte[] { 0x7F }, new BigInteger(0x7F).ToByteArray()); + AssertEqual(new byte[] { 0x45, 0xCC, 0xD0 }, new BigInteger(-0x2F33BB).ToByteArray()); + AssertEqual(new byte[] { 0 }, new BigInteger(0).ToByteArray()); + AssertEqual(new byte[] { 0 }, new BigInteger().ToByteArray()); + } + + [TestMethod] + public void TestLongCtorToByteArray() + { + AssertEqual(new byte[] { 0x01 }, new BigInteger(0x01L).ToByteArray()); + AssertEqual(new byte[] { 0x02, 0x01 }, new BigInteger(0x0102L).ToByteArray()); + AssertEqual(new byte[] { 0x03, 0x02, 0x01 }, new BigInteger(0x010203L).ToByteArray()); + AssertEqual(new byte[] { 0x04, 0x03, 0x2, 0x01 }, new BigInteger(0x01020304L).ToByteArray()); + AssertEqual(new byte[] { 0x05, 0x04, 0x03, 0x2, 0x01 }, new BigInteger(0x0102030405L).ToByteArray()); + AssertEqual(new byte[] { 0x06, 0x05, 0x04, 0x03, 0x2, 0x01 }, new BigInteger(0x010203040506L).ToByteArray()); + AssertEqual(new byte[] { 0x07, 0x06, 0x05, 0x04, 0x03, 0x2, 0x01 }, new BigInteger(0x01020304050607L).ToByteArray()); + AssertEqual(new byte[] { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x2, 0x01 }, new BigInteger(0x0102030405060708L).ToByteArray()); + + AssertEqual(new byte[] { 0xFF }, new BigInteger(-0x01L).ToByteArray()); + AssertEqual(new byte[] { 0xFE, 0xFE }, new BigInteger(-0x0102L).ToByteArray()); + AssertEqual(new byte[] { 0xFD, 0xFD, 0xFE }, new BigInteger(-0x010203L).ToByteArray()); + AssertEqual(new byte[] { 0xFC, 0xFC, 0xFD, 0xFE }, new BigInteger(-0x01020304L).ToByteArray()); + AssertEqual(new byte[] { 0xFB, 0xFB, 0xFC, 0xFD, 0xFE }, new BigInteger(-0x0102030405L).ToByteArray()); + AssertEqual(new byte[] { 0xFA, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE }, new BigInteger(-0x010203040506L).ToByteArray()); + AssertEqual(new byte[] { 0xF9, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE }, new BigInteger(-0x01020304050607L).ToByteArray()); + AssertEqual(new byte[] { 0xF8, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE }, new BigInteger(-0x0102030405060708L).ToByteArray()); + + AssertEqual(new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F }, new BigInteger(long.MaxValue).ToByteArray()); + AssertEqual(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 }, new BigInteger(long.MinValue).ToByteArray()); + + AssertEqual(new byte[] { 0xFF, 0xFF, 0xFF, 0x7F, 0xFF }, new BigInteger(-2147483649L).ToByteArray()); + } + + [TestMethod] + public void CompareTo() + { + var a = new BigInteger(99); + Assert.AreEqual(-1, a.CompareTo(100), "#1"); + Assert.AreEqual(1, a.CompareTo(null), "#2"); + } + + [TestMethod] + public void ShortOperators() + { + Assert.AreEqual(22, (int)new BigInteger((short)22), "#1"); + Assert.AreEqual(-22, (int)new BigInteger((short)-22), "#2"); + + try + { + short x = (short)new BigInteger(10000000); + Assert.Fail("#3"); + } + catch (OverflowException) { } + + try + { + short x = (short)new BigInteger(-10000000); + Assert.Fail("#4"); + } + catch (OverflowException) { } + } + + [TestMethod] + public void Ctor_Double_NaN() + { + try + { + new BigInteger(double.NaN); + Assert.Fail(); + } + catch (OverflowException) + { + } + } + + [TestMethod] + public void Ctor_Double_NegativeInfinity() + { + try + { + new BigInteger(double.NegativeInfinity); + Assert.Fail(); + } + catch (OverflowException) + { + } + } + + [TestMethod] + public void Ctor_Double_PositiveInfinity() + { + try + { + new BigInteger(double.PositiveInfinity); + Assert.Fail(); + } + catch (OverflowException) + { + } + } + + [TestMethod] + public void Ctor_Double() + { + Assert.AreEqual(10000, (int)new BigInteger(10000.2)); + Assert.AreEqual(10000, (int)new BigInteger(10000.9)); + Assert.AreEqual(10000, (int)new BigInteger(10000.2)); + Assert.AreEqual(0, (int)new BigInteger(0.9)); + Assert.AreEqual(12345678999L, (long)new BigInteger(12345678999.33)); + } + + [TestMethod] + public void DoubleConversion() + { + Assert.AreEqual(999d, (double)new BigInteger(999), "#1"); + Assert.AreEqual(double.PositiveInfinity, (double)BigInteger.Pow(2, 1024), "#2"); + Assert.AreEqual(double.NegativeInfinity, (double)BigInteger.Pow(-2, 1025), "#3"); + + Assert.AreEqual(0d, (double)BigInteger.Zero, "#4"); + Assert.AreEqual(1d, (double)BigInteger.One, "#5"); + Assert.AreEqual(-1d, (double)BigInteger.MinusOne, "#6"); + + var result1 = BitConverter.Int64BitsToDouble(-4337852273739220173); + Assert.AreEqual(result1, (double)new BigInteger(new byte[] { 53, 152, 137, 177, 240, 81, 75, 198 }), "#7"); + var result2 = BitConverter.Int64BitsToDouble(4893382453283402035); + Assert.AreEqual(result2, (double)new BigInteger(new byte[] { 53, 152, 137, 177, 240, 81, 75, 198, 0 }), "#8"); + + var result3 = BitConverter.Int64BitsToDouble(5010775143622804480); + var result4 = BitConverter.Int64BitsToDouble(5010775143622804481); + var result5 = BitConverter.Int64BitsToDouble(5010775143622804482); + Assert.AreEqual(result3, (double)new BigInteger(new byte[] { 0, 0, 0, 0, 16, 128, 208, 159, 60, 46, 59, 3 }), "#9"); + Assert.AreEqual(result3, (double)new BigInteger(new byte[] { 0, 0, 0, 0, 17, 128, 208, 159, 60, 46, 59, 3 }), "#10"); + Assert.AreEqual(result3, (double)new BigInteger(new byte[] { 0, 0, 0, 0, 24, 128, 208, 159, 60, 46, 59, 3 }), "#11"); + Assert.AreEqual(result4, (double)new BigInteger(new byte[] { 0, 0, 0, 0, 32, 128, 208, 159, 60, 46, 59, 3 }), "#12"); + Assert.AreEqual(result4, (double)new BigInteger(new byte[] { 0, 0, 0, 0, 48, 128, 208, 159, 60, 46, 59, 3 }), "#13"); + Assert.AreEqual(result5, (double)new BigInteger(new byte[] { 0, 0, 0, 0, 64, 128, 208, 159, 60, 46, 59, 3 }), "#14"); + + Assert.AreEqual(BitConverter.Int64BitsToDouble(-2748107935317889142), (double)new BigInteger(huge_a), "#15"); + Assert.AreEqual(BitConverter.Int64BitsToDouble(-2354774254443231289), (double)new BigInteger(huge_b), "#16"); + Assert.AreEqual(BitConverter.Int64BitsToDouble(8737073938546854790), (double)new BigInteger(huge_mul), "#17"); + + Assert.AreEqual(BitConverter.Int64BitsToDouble(6912920136897069886), (double)(2278888483353476799 * BigInteger.Pow(2, 451)), "#18"); + Assert.AreEqual(double.PositiveInfinity, (double)(843942696292817306 * BigInteger.Pow(2, 965)), "#19"); + } + + [TestMethod] + public void DecimalCtor() + { + Assert.AreEqual(999, (int)new BigInteger(999.99m), "#1"); + Assert.AreEqual(-10000, (int)new BigInteger(-10000m), "#2"); + Assert.AreEqual(0, (int)new BigInteger(0m), "#3"); + } + + [TestMethod] + public void DecimalConversion() + { + Assert.AreEqual(999m, (decimal)new BigInteger(999), "#1"); + + try + { + var x = (decimal) BigInteger.Pow(2, 1024); + Assert.Fail("#2: " + x); + } + catch (OverflowException) + { + } + + try + { + var x = (decimal) BigInteger.Pow(-2, 1025); + Assert.Fail("#3: " + x); + } + catch (OverflowException) + { + } + + Assert.AreEqual(0m, (decimal)new BigInteger(0), "#4"); + Assert.AreEqual(1m, (decimal)new BigInteger(1), "#5"); + Assert.AreEqual(-1m, (decimal)new BigInteger(-1), "#6"); + Assert.AreEqual(9999999999999999999999999999m, (decimal)new BigInteger(9999999999999999999999999999m), "#7"); + Assert.AreEqual(0m, (decimal)new BigInteger(), "#8"); + } + + [TestMethod] + public void Parse() + { + try + { + BigInteger.Parse(null); + Assert.Fail("#1"); + } + catch (ArgumentNullException) { } + + try + { + BigInteger.Parse(""); + Assert.Fail("#2"); + } + catch (FormatException) { } + + + try + { + BigInteger.Parse(" "); + Assert.Fail("#3"); + } + catch (FormatException) { } + + try + { + BigInteger.Parse("hh"); + Assert.Fail("#4"); + } + catch (FormatException) { } + + try + { + BigInteger.Parse("-"); + Assert.Fail("#5"); + } + catch (FormatException) { } + + try + { + BigInteger.Parse("-+"); + Assert.Fail("#6"); + } + catch (FormatException) { } + + Assert.AreEqual(10, (int)BigInteger.Parse("+10"), "#7"); + Assert.AreEqual(10, (int)BigInteger.Parse("10 "), "#8"); + Assert.AreEqual(-10, (int)BigInteger.Parse("-10 "), "#9"); + Assert.AreEqual(10, (int)BigInteger.Parse(" 10 "), "#10"); + Assert.AreEqual(-10, (int)BigInteger.Parse(" -10 "), "#11"); + + Assert.AreEqual(-1, (int)BigInteger.Parse("F", NumberStyles.AllowHexSpecifier), "#12"); + Assert.AreEqual(-8, (int)BigInteger.Parse("8", NumberStyles.AllowHexSpecifier), "#13"); + Assert.AreEqual(8, (int)BigInteger.Parse("08", NumberStyles.AllowHexSpecifier), "#14"); + Assert.AreEqual(15, (int)BigInteger.Parse("0F", NumberStyles.AllowHexSpecifier), "#15"); + Assert.AreEqual(-1, (int)BigInteger.Parse("FF", NumberStyles.AllowHexSpecifier), "#16"); + Assert.AreEqual(255, (int)BigInteger.Parse("0FF", NumberStyles.AllowHexSpecifier), "#17"); + + Assert.AreEqual(-17, (int)BigInteger.Parse(" (17) ", NumberStyles.AllowParentheses | NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite), "#18"); + Assert.AreEqual(-23, (int)BigInteger.Parse(" -23 ", NumberStyles.AllowLeadingSign | NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite), "#19"); + + Assert.AreEqual(300000, (int)BigInteger.Parse("3E5", NumberStyles.AllowExponent), "#20"); + var dsep = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator; + Assert.AreEqual(250, (int)BigInteger.Parse("2" + dsep + "5E2", NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint), "#21");//2.5E2 = 250 + Assert.AreEqual(25, (int)BigInteger.Parse("2500E-2", NumberStyles.AllowExponent), "#22"); + + Assert.AreEqual("136236974127783066520110477975349088954559032721408", BigInteger.Parse("136236974127783066520110477975349088954559032721408", NumberStyles.None).ToString(), "#23"); + Assert.AreEqual("136236974127783066520110477975349088954559032721408", BigInteger.Parse("136236974127783066520110477975349088954559032721408").ToString(), "#24"); + + try + { + BigInteger.Parse("2E3.0", NumberStyles.AllowExponent); // decimal notation for the exponent + Assert.Fail("#25"); + } + catch (FormatException) + { + } + + try + { + Int32.Parse("2" + dsep + "09E1", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent); + Assert.Fail("#26"); + } + catch (OverflowException) + { + } + } + + [TestMethod] + public void TryParse() + { + BigInteger x; + + Assert.IsFalse(BigInteger.TryParse(null, out x), "#1"); + Assert.AreEqual(0, (int)x, "#1a"); + Assert.IsFalse(BigInteger.TryParse("", out x), "#2"); + Assert.IsFalse(BigInteger.TryParse(" ", out x), "#3"); + Assert.IsFalse(BigInteger.TryParse(" -", out x), "#4"); + Assert.IsFalse(BigInteger.TryParse(" +", out x), "#5"); + Assert.IsFalse(BigInteger.TryParse(" FF", out x), "#6"); + + Assert.IsTrue(BigInteger.TryParse(" 99", out x), "#7"); + Assert.AreEqual(99, (int)x, "#8"); + + Assert.IsTrue(BigInteger.TryParse("+133", out x), "#9"); + Assert.AreEqual(133, (int)x, "#10"); + + Assert.IsTrue(BigInteger.TryParse("-010", out x), "#11"); + Assert.AreEqual(-10, (int)x, "#12"); + + //Number style and format provider + + Assert.IsFalse(BigInteger.TryParse("null", NumberStyles.None, null, out x), "#13"); + Assert.AreEqual(0, (int)x, "#14"); + Assert.IsFalse(BigInteger.TryParse("-10", NumberStyles.None, null, out x), "#15"); + Assert.IsFalse(BigInteger.TryParse("(10)", NumberStyles.None, null, out x), "#16"); + Assert.IsFalse(BigInteger.TryParse(" 10", NumberStyles.None, null, out x), "#17"); + Assert.IsFalse(BigInteger.TryParse("10 ", NumberStyles.None, null, out x), "#18"); + + Assert.IsTrue(BigInteger.TryParse("-10", NumberStyles.AllowLeadingSign, null, out x), "#19"); + Assert.AreEqual(-10, (int)x, "#20"); + Assert.IsTrue(BigInteger.TryParse("(10)", NumberStyles.AllowParentheses, null, out x), "#21"); + Assert.AreEqual(-10, (int)x, "#22"); + Assert.IsTrue(BigInteger.TryParse(" 10", NumberStyles.AllowLeadingWhite, null, out x), "#23"); + Assert.AreEqual(10, (int)x, "#24"); + Assert.IsTrue(BigInteger.TryParse("10 ", NumberStyles.AllowTrailingWhite, null, out x), "#25"); + Assert.AreEqual(10, (int)x, "#26"); + + Assert.IsFalse(BigInteger.TryParse("$10", NumberStyles.None, null, out x), "#26"); + Assert.IsFalse(BigInteger.TryParse("$10", NumberStyles.None, _nfi, out x), "#27"); + Assert.IsFalse(BigInteger.TryParse("%10", NumberStyles.None, _nfi, out x), "#28"); + Assert.IsFalse(BigInteger.TryParse("10 ", NumberStyles.None, null, out x), "#29"); + + Assert.IsTrue(BigInteger.TryParse("10", NumberStyles.None, null, out x), "#30"); + Assert.AreEqual(10, (int)x, "#31"); + Assert.IsTrue(BigInteger.TryParse(_nfi.CurrencySymbol + "10", NumberStyles.AllowCurrencySymbol, _nfi, out x), "#32"); + Assert.AreEqual(10, (int)x, "#33"); + Assert.IsFalse(BigInteger.TryParse("%10", NumberStyles.AllowCurrencySymbol, _nfi, out x), "#34"); + } + + [TestMethod] + public void TestUserCurrency() + { + const int val1 = -1234567; + const int val2 = 1234567; + + var s = val1.ToString("c", _nfiUser); + Assert.AreEqual("1234/5/67:000 XYZ-", s, "Currency value type 1 is not what we want to try to parse"); + var v = BigInteger.Parse("1234/5/67:000 XYZ-", NumberStyles.Currency, _nfiUser); + Assert.AreEqual(val1, (int) v); + + s = val2.ToString("c", _nfiUser); + Assert.AreEqual("1234/5/67:000 XYZ", s, "Currency value type 2 is not what we want to try to parse"); + v = BigInteger.Parse(s, NumberStyles.Currency, _nfiUser); + Assert.AreEqual(val2, (int)v); + } + + [TestMethod] + public void TryParseWeirdCulture() + { + var old = Thread.CurrentThread.CurrentCulture; + var cur = (CultureInfo)old.Clone(); + + var ninfo = new NumberFormatInfo + { + NegativeSign = ">", + PositiveSign = "%" + }; + cur.NumberFormat = ninfo; + + Thread.CurrentThread.CurrentCulture = cur; + + try + { + BigInteger x; + Assert.IsTrue(BigInteger.TryParse("%11", out x), "#1"); + Assert.AreEqual(11, (int)x, "#2"); + + Assert.IsTrue(BigInteger.TryParse(">11", out x), "#3"); + Assert.AreEqual(-11, (int)x, "#4"); + } + finally + { + Thread.CurrentThread.CurrentCulture = old; + } + } + + [TestMethod] + public void CompareToLongToWithBigNumber() + { + var a = BigInteger.Parse("123456789123456789"); + var b = BigInteger.Parse("-123456789123456789"); + Assert.AreEqual(1, a.CompareTo(2000)); + Assert.AreEqual(1, a.CompareTo(-2000)); + Assert.AreEqual(-1, b.CompareTo(2000)); + Assert.AreEqual(-1, b.CompareTo(-2000)); + } + + [TestMethod] + public void LeftShiftByInt() + { + var v = BigInteger.Parse("230794411440927908251127453634"); + + Assert.AreEqual("230794411440927908251127453634", (v << 0).ToString(), "#0"); + Assert.AreEqual("461588822881855816502254907268", (v << 1).ToString(), "#1"); + Assert.AreEqual("923177645763711633004509814536", (v << 2).ToString(), "#2"); + Assert.AreEqual("1846355291527423266009019629072", (v << 3).ToString(), "#3"); + Assert.AreEqual("3692710583054846532018039258144", (v << 4).ToString(), "#4"); + Assert.AreEqual("7385421166109693064036078516288", (v << 5).ToString(), "#5"); + Assert.AreEqual("14770842332219386128072157032576", (v << 6).ToString(), "#6"); + Assert.AreEqual("29541684664438772256144314065152", (v << 7).ToString(), "#7"); + Assert.AreEqual("59083369328877544512288628130304", (v << 8).ToString(), "#8"); + Assert.AreEqual("118166738657755089024577256260608", (v << 9).ToString(), "#9"); + Assert.AreEqual("236333477315510178049154512521216", (v << 10).ToString(), "#10"); + Assert.AreEqual("472666954631020356098309025042432", (v << 11).ToString(), "#11"); + Assert.AreEqual("945333909262040712196618050084864", (v << 12).ToString(), "#12"); + Assert.AreEqual("1890667818524081424393236100169728", (v << 13).ToString(), "#13"); + Assert.AreEqual("3781335637048162848786472200339456", (v << 14).ToString(), "#14"); + Assert.AreEqual("7562671274096325697572944400678912", (v << 15).ToString(), "#15"); + Assert.AreEqual("15125342548192651395145888801357824", (v << 16).ToString(), "#16"); + Assert.AreEqual("30250685096385302790291777602715648", (v << 17).ToString(), "#17"); + Assert.AreEqual("60501370192770605580583555205431296", (v << 18).ToString(), "#18"); + Assert.AreEqual("121002740385541211161167110410862592", (v << 19).ToString(), "#19"); + Assert.AreEqual("242005480771082422322334220821725184", (v << 20).ToString(), "#20"); + Assert.AreEqual("484010961542164844644668441643450368", (v << 21).ToString(), "#21"); + Assert.AreEqual("968021923084329689289336883286900736", (v << 22).ToString(), "#22"); + Assert.AreEqual("1936043846168659378578673766573801472", (v << 23).ToString(), "#23"); + Assert.AreEqual("3872087692337318757157347533147602944", (v << 24).ToString(), "#24"); + Assert.AreEqual("7744175384674637514314695066295205888", (v << 25).ToString(), "#25"); + Assert.AreEqual("15488350769349275028629390132590411776", (v << 26).ToString(), "#26"); + Assert.AreEqual("30976701538698550057258780265180823552", (v << 27).ToString(), "#27"); + Assert.AreEqual("61953403077397100114517560530361647104", (v << 28).ToString(), "#28"); + Assert.AreEqual("123906806154794200229035121060723294208", (v << 29).ToString(), "#29"); + Assert.AreEqual("247813612309588400458070242121446588416", (v << 30).ToString(), "#30"); + Assert.AreEqual("495627224619176800916140484242893176832", (v << 31).ToString(), "#31"); + Assert.AreEqual("991254449238353601832280968485786353664", (v << 32).ToString(), "#32"); + Assert.AreEqual("1982508898476707203664561936971572707328", (v << 33).ToString(), "#33"); + Assert.AreEqual("3965017796953414407329123873943145414656", (v << 34).ToString(), "#34"); + Assert.AreEqual("7930035593906828814658247747886290829312", (v << 35).ToString(), "#35"); + Assert.AreEqual("15860071187813657629316495495772581658624", (v << 36).ToString(), "#36"); + Assert.AreEqual("31720142375627315258632990991545163317248", (v << 37).ToString(), "#37"); + Assert.AreEqual("63440284751254630517265981983090326634496", (v << 38).ToString(), "#38"); + Assert.AreEqual("126880569502509261034531963966180653268992", (v << 39).ToString(), "#39"); + Assert.AreEqual("253761139005018522069063927932361306537984", (v << 40).ToString(), "#40"); + Assert.AreEqual("507522278010037044138127855864722613075968", (v << 41).ToString(), "#41"); + Assert.AreEqual("1015044556020074088276255711729445226151936", (v << 42).ToString(), "#42"); + Assert.AreEqual("2030089112040148176552511423458890452303872", (v << 43).ToString(), "#43"); + Assert.AreEqual("4060178224080296353105022846917780904607744", (v << 44).ToString(), "#44"); + Assert.AreEqual("8120356448160592706210045693835561809215488", (v << 45).ToString(), "#45"); + Assert.AreEqual("16240712896321185412420091387671123618430976", (v << 46).ToString(), "#46"); + Assert.AreEqual("32481425792642370824840182775342247236861952", (v << 47).ToString(), "#47"); + Assert.AreEqual("64962851585284741649680365550684494473723904", (v << 48).ToString(), "#48"); + Assert.AreEqual("129925703170569483299360731101368988947447808", (v << 49).ToString(), "#49"); + Assert.AreEqual("259851406341138966598721462202737977894895616", (v << 50).ToString(), "#50"); + Assert.AreEqual("519702812682277933197442924405475955789791232", (v << 51).ToString(), "#51"); + Assert.AreEqual("1039405625364555866394885848810951911579582464", (v << 52).ToString(), "#52"); + Assert.AreEqual("2078811250729111732789771697621903823159164928", (v << 53).ToString(), "#53"); + Assert.AreEqual("4157622501458223465579543395243807646318329856", (v << 54).ToString(), "#54"); + Assert.AreEqual("8315245002916446931159086790487615292636659712", (v << 55).ToString(), "#55"); + Assert.AreEqual("16630490005832893862318173580975230585273319424", (v << 56).ToString(), "#56"); + Assert.AreEqual("33260980011665787724636347161950461170546638848", (v << 57).ToString(), "#57"); + Assert.AreEqual("66521960023331575449272694323900922341093277696", (v << 58).ToString(), "#58"); + Assert.AreEqual("133043920046663150898545388647801844682186555392", (v << 59).ToString(), "#59"); + Assert.AreEqual("266087840093326301797090777295603689364373110784", (v << 60).ToString(), "#60"); + Assert.AreEqual("532175680186652603594181554591207378728746221568", (v << 61).ToString(), "#61"); + Assert.AreEqual("1064351360373305207188363109182414757457492443136", (v << 62).ToString(), "#62"); + Assert.AreEqual("2128702720746610414376726218364829514914984886272", (v << 63).ToString(), "#63"); + Assert.AreEqual("4257405441493220828753452436729659029829969772544", (v << 64).ToString(), "#64"); + Assert.AreEqual("8514810882986441657506904873459318059659939545088", (v << 65).ToString(), "#65"); + Assert.AreEqual("17029621765972883315013809746918636119319879090176", (v << 66).ToString(), "#66"); + Assert.AreEqual("34059243531945766630027619493837272238639758180352", (v << 67).ToString(), "#67"); + Assert.AreEqual("68118487063891533260055238987674544477279516360704", (v << 68).ToString(), "#68"); + Assert.AreEqual("136236974127783066520110477975349088954559032721408", (v << 69).ToString(), "#69"); + } + + + [TestMethod] + public void RightShiftByInt() + { + var v = BigInteger.Parse("230794411440927908251127453634"); + v = v * BigInteger.Pow(2, 70); + + Assert.AreEqual("272473948255566133040220955950698177909118065442816", (v >> 0).ToString(), "#0"); + Assert.AreEqual("136236974127783066520110477975349088954559032721408", (v >> 1).ToString(), "#1"); + Assert.AreEqual("68118487063891533260055238987674544477279516360704", (v >> 2).ToString(), "#2"); + Assert.AreEqual("34059243531945766630027619493837272238639758180352", (v >> 3).ToString(), "#3"); + Assert.AreEqual("17029621765972883315013809746918636119319879090176", (v >> 4).ToString(), "#4"); + Assert.AreEqual("8514810882986441657506904873459318059659939545088", (v >> 5).ToString(), "#5"); + Assert.AreEqual("4257405441493220828753452436729659029829969772544", (v >> 6).ToString(), "#6"); + Assert.AreEqual("2128702720746610414376726218364829514914984886272", (v >> 7).ToString(), "#7"); + Assert.AreEqual("1064351360373305207188363109182414757457492443136", (v >> 8).ToString(), "#8"); + Assert.AreEqual("532175680186652603594181554591207378728746221568", (v >> 9).ToString(), "#9"); + Assert.AreEqual("266087840093326301797090777295603689364373110784", (v >> 10).ToString(), "#10"); + Assert.AreEqual("133043920046663150898545388647801844682186555392", (v >> 11).ToString(), "#11"); + Assert.AreEqual("66521960023331575449272694323900922341093277696", (v >> 12).ToString(), "#12"); + Assert.AreEqual("33260980011665787724636347161950461170546638848", (v >> 13).ToString(), "#13"); + Assert.AreEqual("16630490005832893862318173580975230585273319424", (v >> 14).ToString(), "#14"); + Assert.AreEqual("8315245002916446931159086790487615292636659712", (v >> 15).ToString(), "#15"); + Assert.AreEqual("4157622501458223465579543395243807646318329856", (v >> 16).ToString(), "#16"); + Assert.AreEqual("2078811250729111732789771697621903823159164928", (v >> 17).ToString(), "#17"); + Assert.AreEqual("1039405625364555866394885848810951911579582464", (v >> 18).ToString(), "#18"); + Assert.AreEqual("519702812682277933197442924405475955789791232", (v >> 19).ToString(), "#19"); + Assert.AreEqual("259851406341138966598721462202737977894895616", (v >> 20).ToString(), "#20"); + Assert.AreEqual("129925703170569483299360731101368988947447808", (v >> 21).ToString(), "#21"); + Assert.AreEqual("64962851585284741649680365550684494473723904", (v >> 22).ToString(), "#22"); + Assert.AreEqual("32481425792642370824840182775342247236861952", (v >> 23).ToString(), "#23"); + Assert.AreEqual("16240712896321185412420091387671123618430976", (v >> 24).ToString(), "#24"); + Assert.AreEqual("8120356448160592706210045693835561809215488", (v >> 25).ToString(), "#25"); + Assert.AreEqual("4060178224080296353105022846917780904607744", (v >> 26).ToString(), "#26"); + Assert.AreEqual("2030089112040148176552511423458890452303872", (v >> 27).ToString(), "#27"); + Assert.AreEqual("1015044556020074088276255711729445226151936", (v >> 28).ToString(), "#28"); + Assert.AreEqual("507522278010037044138127855864722613075968", (v >> 29).ToString(), "#29"); + Assert.AreEqual("253761139005018522069063927932361306537984", (v >> 30).ToString(), "#30"); + Assert.AreEqual("126880569502509261034531963966180653268992", (v >> 31).ToString(), "#31"); + Assert.AreEqual("63440284751254630517265981983090326634496", (v >> 32).ToString(), "#32"); + Assert.AreEqual("31720142375627315258632990991545163317248", (v >> 33).ToString(), "#33"); + Assert.AreEqual("15860071187813657629316495495772581658624", (v >> 34).ToString(), "#34"); + Assert.AreEqual("7930035593906828814658247747886290829312", (v >> 35).ToString(), "#35"); + Assert.AreEqual("3965017796953414407329123873943145414656", (v >> 36).ToString(), "#36"); + Assert.AreEqual("1982508898476707203664561936971572707328", (v >> 37).ToString(), "#37"); + Assert.AreEqual("991254449238353601832280968485786353664", (v >> 38).ToString(), "#38"); + Assert.AreEqual("495627224619176800916140484242893176832", (v >> 39).ToString(), "#39"); + Assert.AreEqual("247813612309588400458070242121446588416", (v >> 40).ToString(), "#40"); + Assert.AreEqual("123906806154794200229035121060723294208", (v >> 41).ToString(), "#41"); + Assert.AreEqual("61953403077397100114517560530361647104", (v >> 42).ToString(), "#42"); + Assert.AreEqual("30976701538698550057258780265180823552", (v >> 43).ToString(), "#43"); + Assert.AreEqual("15488350769349275028629390132590411776", (v >> 44).ToString(), "#44"); + Assert.AreEqual("7744175384674637514314695066295205888", (v >> 45).ToString(), "#45"); + Assert.AreEqual("3872087692337318757157347533147602944", (v >> 46).ToString(), "#46"); + Assert.AreEqual("1936043846168659378578673766573801472", (v >> 47).ToString(), "#47"); + Assert.AreEqual("968021923084329689289336883286900736", (v >> 48).ToString(), "#48"); + Assert.AreEqual("484010961542164844644668441643450368", (v >> 49).ToString(), "#49"); + Assert.AreEqual("242005480771082422322334220821725184", (v >> 50).ToString(), "#50"); + Assert.AreEqual("121002740385541211161167110410862592", (v >> 51).ToString(), "#51"); + Assert.AreEqual("60501370192770605580583555205431296", (v >> 52).ToString(), "#52"); + Assert.AreEqual("30250685096385302790291777602715648", (v >> 53).ToString(), "#53"); + Assert.AreEqual("15125342548192651395145888801357824", (v >> 54).ToString(), "#54"); + Assert.AreEqual("7562671274096325697572944400678912", (v >> 55).ToString(), "#55"); + Assert.AreEqual("3781335637048162848786472200339456", (v >> 56).ToString(), "#56"); + Assert.AreEqual("1890667818524081424393236100169728", (v >> 57).ToString(), "#57"); + Assert.AreEqual("945333909262040712196618050084864", (v >> 58).ToString(), "#58"); + Assert.AreEqual("472666954631020356098309025042432", (v >> 59).ToString(), "#59"); + Assert.AreEqual("236333477315510178049154512521216", (v >> 60).ToString(), "#60"); + Assert.AreEqual("118166738657755089024577256260608", (v >> 61).ToString(), "#61"); + Assert.AreEqual("59083369328877544512288628130304", (v >> 62).ToString(), "#62"); + Assert.AreEqual("29541684664438772256144314065152", (v >> 63).ToString(), "#63"); + Assert.AreEqual("14770842332219386128072157032576", (v >> 64).ToString(), "#64"); + Assert.AreEqual("7385421166109693064036078516288", (v >> 65).ToString(), "#65"); + Assert.AreEqual("3692710583054846532018039258144", (v >> 66).ToString(), "#66"); + Assert.AreEqual("1846355291527423266009019629072", (v >> 67).ToString(), "#67"); + Assert.AreEqual("923177645763711633004509814536", (v >> 68).ToString(), "#68"); + Assert.AreEqual("461588822881855816502254907268", (v >> 69).ToString(), "#69"); + } + + [TestMethod] + public void Bug10887() + { + BigInteger b = 0; + for (int i = 1; i <= 16; i++) + b = b * 256 + i; + BigInteger p = BigInteger.Pow(2, 32); + Assert.AreEqual("1339673755198158349044581307228491536", b.ToString(), "#1"); + Assert.AreEqual("1339673755198158349044581307228491536", ((b << 32) / p).ToString(), "#2"); + Assert.AreEqual("1339673755198158349044581307228491536", (b * p >> 32).ToString(), "#3"); + } + + [TestMethod] + public void DefaultCtorWorks() + { + var a = new BigInteger(); + Assert.AreEqual(BigInteger.One, ++a, "#1"); + + a = new BigInteger(); + Assert.AreEqual(BigInteger.MinusOne, --a, "#2"); + + a = new BigInteger(); + Assert.AreEqual(BigInteger.MinusOne, ~a, "#3"); + + a = new BigInteger(); + Assert.AreEqual("0", a.ToString(), "#4"); + + a = new BigInteger(); + Assert.AreEqual(true, a == a, "#5"); + + a = new BigInteger(); + Assert.AreEqual(false, a < a, "#6"); + + a = new BigInteger(); + Assert.AreEqual(true, a < 10l, "#7"); + + a = new BigInteger(); + Assert.AreEqual(true, a.IsEven, "#8"); + + a = new BigInteger(); + Assert.AreEqual(0, (int)a, "#9"); + + a = new BigInteger(); + Assert.AreEqual((uint) 0, (uint)a, "#10"); + + a = new BigInteger(); + Assert.AreEqual((ulong) 0, (ulong)a, "#11"); + + a = new BigInteger(); + Assert.AreEqual(true, a.Equals(a), "#12"); + + a = new BigInteger(); + Assert.AreEqual(a, BigInteger.Min(a, a), "#13"); + + a = new BigInteger(); + Assert.AreEqual(a, BigInteger.GreatestCommonDivisor(a, a), "#14"); + + a = new BigInteger(); + Assert.AreEqual(BigInteger.Zero.GetHashCode(), a.GetHashCode(), "#15"); + + a = new BigInteger(); + Assert.AreEqual(BigInteger.Zero, a, "#16"); + } + + [TestMethod] + public void Bug16526() + { + var x = BigInteger.Pow(2, 63); + x *= -1; + x -= 1; + Assert.AreEqual("-9223372036854775809", x.ToString(), "#1"); + try + { + x = (long)x; + Assert.Fail("#2 Must OVF: " + x); + } + catch (OverflowException) + { + } + } + + [TestMethod] + //[Ignore] + public void ToArray_Performance() + { + const int loopCount = 100000000; + var bigInteger = new BigInteger(huge_a); + + var stopWatch = new Stopwatch(); + + GC.Collect(); + GC.WaitForFullGCComplete(); + + stopWatch.Start(); + + for (var i = 0; i < loopCount; i++) + { + bigInteger.ToByteArray(); + } + + GC.Collect(); + GC.WaitForFullGCComplete(); + + stopWatch.Stop(); + + Console.WriteLine(stopWatch.ElapsedMilliseconds); + } + + [TestMethod] + //[Ignore] + public void Ctor_ByteArray_Performance() + { + const int loopCount = 100000000; + + var stopWatch = new Stopwatch(); + + GC.Collect(); + GC.WaitForFullGCComplete(); + + stopWatch.Start(); + + for (var i = 0; i < loopCount; i++) + { + new BigInteger(huge_a); + } + + GC.Collect(); + GC.WaitForFullGCComplete(); + + stopWatch.Stop(); + + Console.WriteLine(stopWatch.ElapsedMilliseconds); + } + + [TestMethod] + public void MinusOne() + { + var minusOne = BigInteger.MinusOne; + + Assert.IsFalse(minusOne.IsEven); + Assert.IsFalse(minusOne.IsOne); + Assert.IsFalse(minusOne.IsPowerOfTwo); + Assert.IsFalse(minusOne.IsZero); + Assert.AreEqual(-1, minusOne.Sign); + } + + [TestMethod] + public void One() + { + var one = BigInteger.One; + + Assert.IsFalse(one.IsEven); + Assert.IsTrue(one.IsOne); + Assert.IsTrue(one.IsPowerOfTwo); + Assert.IsFalse(one.IsZero); + Assert.AreEqual(1, one.Sign); + } + + [TestMethod] + public void Zero() + { + var zero = BigInteger.Zero; + + Assert.IsTrue(zero.IsEven); + Assert.IsFalse(zero.IsOne); + Assert.IsFalse(zero.IsPowerOfTwo); + Assert.IsTrue(zero.IsZero); + Assert.AreEqual(0, zero.Sign); + } + + private static void AssertEqual(byte[] a, byte[] b) + { + if (!a.IsEqualTo(b)) + throw new AssertFailedException(); + } + } } diff --git a/src/Renci.SshNet/Common/BigInteger.cs b/src/Renci.SshNet/Common/BigInteger.cs index d7097586..6166f428 100644 --- a/src/Renci.SshNet/Common/BigInteger.cs +++ b/src/Renci.SshNet/Common/BigInteger.cs @@ -1,10 +1,12 @@ -// vim: noet -// System.Numerics.BigInt +// +// System.Numerics.BigInteger // -// Rodrigo Kumpera (rkumpera@novell.com) - +// Authors: +// Rodrigo Kumpera (rkumpera@novell.com) +// Marek Safar // // Copyright (C) 2010 Novell, Inc (http://www.novell.com) +// Copyright (C) 2014 Xamarin Inc (http://www.xamarin.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -13,10 +15,10 @@ // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: -// +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -25,7 +27,7 @@ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -// A big chuck of code comes the DLR (as hosted in http://ironpython.codeplex.com), +// A big chuck of code comes the DLR (as hosted in http://ironpython.codeplex.com), // which has the following License: // /* **************************************************************************** @@ -42,40 +44,52 @@ * * * ***************************************************************************/ +// +// slashdocs based on MSDN using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Globalization; +using System.Threading; using Renci.SshNet.Security.Cryptography; /* Optimization -Have proper popcount function for IsPowerOfTwo -Use unsafe ops to avoid bounds check -CoreAdd could avoid some resizes by checking for equal sized array that top overflow -For bitwise operators, hoist the conditionals out of their main loop -Optimize BitScanBackward -Use a carry variable to make shift opts do half the number of array ops. -Schoolbook multiply is O(n^2), use Karatsuba /Toom-3 for large numbers + Have proper popcount function for IsPowerOfTwo + Use unsafe ops to avoid bounds check + CoreAdd could avoid some resizes by checking for equal sized array that top overflow + For bitwise operators, hoist the conditionals out of their main loop + Optimize BitScanBackward + Use a carry variable to make shift opts do half the number of array ops. + Schoolbook multiply is O(n^2), use Karatsuba /Toom-3 for large numbers */ namespace Renci.SshNet.Common { /// /// Represents an arbitrarily large signed integer. /// + [SuppressMessage("ReSharper", "EmptyEmbeddedStatement")] + [SuppressMessage("ReSharper", "RedundantCast")] + [SuppressMessage("ReSharper", "RedundantAssignment")] + [SuppressMessage("ReSharper", "SuggestBaseTypeForParameter")] + [SuppressMessage("ReSharper", "MergeConditionalExpression")] public struct BigInteger : IComparable, IFormattable, IComparable, IEquatable { - private const ulong Base = 0x100000000; - private const int Decimalsignmask = unchecked((int)0x80000000); - private const int Bias = 1075; + private static readonly BigInteger ZeroSingleton = new BigInteger(0); + private static readonly BigInteger OneSingleton = new BigInteger(1); + private static readonly BigInteger MinusOneSingleton = new BigInteger(-1); - private static readonly uint[] _zero = new uint[1]; - private static readonly uint[] _one = { 1 }; + private const ulong Base = 0x100000000; + private const int Bias = 1075; + private const int DecimalSignMask = unchecked((int) 0x80000000); //LSB on [0] private readonly uint[] _data; private readonly short _sign; + #region SSH.NET additions + /// /// Gets number of bits used by the number. /// @@ -100,52 +114,114 @@ namespace Renci.SshNet.Common } } - #region Constractors + /// + /// Mods the inverse. + /// + /// The bi. + /// The modulus. + /// + /// Modulus inverted number. + /// + public static BigInteger ModInverse(BigInteger bi, BigInteger modulus) + { + BigInteger a = modulus, b = bi % modulus; + BigInteger p0 = 0, p1 = 1; + + while (!b.IsZero) + { + if (b.IsOne) + return p1; + + p0 += (a / b) * p1; + a %= b; + + if (a.IsZero) + break; + + if (a.IsOne) + return modulus - p0; + + p1 += (b / a) * p0; + b %= a; + + } + return 0; + } /// - /// Initializes a new instance of the struct. + /// Returns positive remainder that results from division with two specified values. /// - /// The sign. - /// The data. - public BigInteger(short sign, uint[] data) + /// The value to be divided. + /// The value to divide by. + /// + /// Positive remainder that results from the division. + /// + public static BigInteger PositiveMod(BigInteger dividend, BigInteger divisor) + { + var result = dividend % divisor; + if (result < 0) + result += divisor; + + return result; + } + + /// + /// Generates random number. + /// + /// Length of random number in bits. + /// + /// A random number. + /// + public static BigInteger Random(int bitLength) + { + var bytesArray = new byte[bitLength / 8 + (((bitLength % 8) > 0) ? 1 : 0)]; + HashAlgorithmFactory.GenerateRandom(bytesArray); + bytesArray[bytesArray.Length - 1] = (byte)(bytesArray[bytesArray.Length - 1] & 0x7F); // Ensure not a negative value + return new BigInteger(bytesArray); + } + + #endregion SSH.NET additions + + private BigInteger(short sign, uint[] data) { _sign = sign; _data = data; } /// - /// Initializes a new instance of the struct. + /// Initializes a new instance of the structure using a 32-bit signed integer value. /// - /// The value. + /// A 32-bit signed integer. public BigInteger(int value) { if (value == 0) { _sign = 0; - _data = _zero; + _data = null; } else if (value > 0) { _sign = 1; - _data = new[] { (uint)value }; + _data = new[] {(uint) value}; } else { _sign = -1; - _data = new[] { (uint)-value }; + _data = new[] {(uint) -value}; } } /// - /// Initializes a new instance of the struct. + /// Initializes a new instance of the structure using an unsigned 32-bit integer value. /// - /// The value. + /// An unsigned 32-bit integer value. + [CLSCompliant(false)] public BigInteger(uint value) { if (value == 0) { _sign = 0; - _data = _zero; + _data = null; } else { @@ -155,21 +231,21 @@ namespace Renci.SshNet.Common } /// - /// Initializes a new instance of the struct. + /// Initializes a new instance of the structure using a 64-bit signed integer value. /// - /// The value. + /// A 64-bit signed integer. public BigInteger(long value) { if (value == 0) { _sign = 0; - _data = _zero; + _data = null; } else if (value > 0) { _sign = 1; - uint low = (uint)value; - uint high = (uint)(value >> 32); + var low = (uint)value; + var high = (uint)(value >> 32); _data = new uint[high != 0 ? 2 : 1]; _data[0] = low; @@ -180,8 +256,8 @@ namespace Renci.SshNet.Common { _sign = -1; value = -value; - uint low = (uint)value; - uint high = (uint)((ulong)value >> 32); + var low = (uint)value; + var high = (uint)((ulong)value >> 32); _data = new uint[high != 0 ? 2 : 1]; _data[0] = low; @@ -191,21 +267,22 @@ namespace Renci.SshNet.Common } /// - /// Initializes a new instance of the struct. + /// Initializes a new instance of the structure with an unsigned 64-bit integer value. /// - /// The value. + /// An unsigned 64-bit integer. + [CLSCompliant(false)] public BigInteger(ulong value) { if (value == 0) { _sign = 0; - _data = _zero; + _data = null; } else { _sign = 1; - uint low = (uint)value; - uint high = (uint)(value >> 32); + var low = (uint)value; + var high = (uint)(value >> 32); _data = new uint[high != 0 ? 2 : 1]; _data[0] = low; @@ -214,17 +291,35 @@ namespace Renci.SshNet.Common } } + private static bool Negative(byte[] v) + { + return ((v[7] & 0x80) != 0); + } + + private static ushort Exponent(byte[] v) + { + return (ushort)((((ushort)(v[7] & 0x7F)) << (ushort)4) | (((ushort)(v[6] & 0xF0)) >> 4)); + } + + private static ulong Mantissa(byte[] v) + { + var i1 = ((uint)v[0] | ((uint)v[1] << 8) | ((uint)v[2] << 16) | ((uint)v[3] << 24)); + var i2 = ((uint)v[4] | ((uint)v[5] << 8) | ((uint)(v[6] & 0xF) << 16)); + + return (ulong)((ulong)i1 | ((ulong)i2 << 32)); + } + /// - /// Initializes a new instance of the struct. + /// Initializes a new instance of the structure using a double-precision floating-point value. /// - /// The value. + /// A double-precision floating-point value. public BigInteger(double value) { - if (double.IsNaN(value) || Double.IsInfinity(value)) + if (double.IsNaN(value) || double.IsInfinity(value)) throw new OverflowException(); - byte[] bytes = BitConverter.GetBytes(value); - ulong mantissa = Mantissa(bytes); + var bytes = BitConverter.GetBytes(value); + var mantissa = Mantissa(bytes); if (mantissa == 0) { // 1.0 * 2**exp, we have a power of 2 @@ -232,11 +327,11 @@ namespace Renci.SshNet.Common if (exponent == 0) { _sign = 0; - _data = _zero; + _data = null; return; } - BigInteger res = Negative(bytes) ? MinusOne : One; + var res = Negative(bytes) ? MinusOne : One; res = res << (exponent - 0x3ff); _sign = res._sign; _data = res._data; @@ -255,34 +350,33 @@ namespace Renci.SshNet.Common } /// - /// Initializes a new instance of the struct. + /// Initializes a new instance of the structure using a single-precision floating-point value. /// - /// The value. - public BigInteger(float value) - : this((double)value) + /// A single-precision floating-point value. + public BigInteger(float value) : this((double)value) { } /// - /// Initializes a new instance of the struct. + /// Initializes a new instance of the structure using a value. /// - /// The value. + /// A decimal number. public BigInteger(decimal value) { // First truncate to get scale to 0 and extract bits - int[] bits = Decimal.GetBits(Decimal.Truncate(value)); + var bits = decimal.GetBits(decimal.Truncate(value)); - int size = 3; + var size = 3; while (size > 0 && bits[size - 1] == 0) size--; if (size == 0) { _sign = 0; - _data = _zero; + _data = null; return; } - _sign = (short)((bits[3] & Decimalsignmask) != 0 ? -1 : 1); + _sign = (short)((bits[3] & DecimalSignMask) != 0 ? -1 : 1); _data = new uint[size]; _data[0] = (uint)bits[0]; @@ -293,20 +387,22 @@ namespace Renci.SshNet.Common } /// - /// Initializes a new instance of the struct. + /// Initializes a new instance of the structure using the values in a byte array. /// - /// The value. + /// An array of values in little-endian order. + /// is null. + [CLSCompliant(false)] public BigInteger(byte[] value) { if (value == null) throw new ArgumentNullException("value"); - int len = value.Length; + var len = value.Length; if (len == 0 || (len == 1 && value[0] == 0)) { _sign = 0; - _data = _zero; + _data = null; return; } @@ -318,7 +414,14 @@ namespace Renci.SshNet.Common if (_sign == 1) { while (value[len - 1] == 0) - --len; + { + if (--len == 0) + { + _sign = 0; + _data = null; + return; + } + } int size; var fullWords = size = len / 4; @@ -329,10 +432,10 @@ namespace Renci.SshNet.Common var j = 0; for (var i = 0; i < fullWords; ++i) { - _data[i] = (uint)value[j++] | - (uint)(value[j++] << 8) | - (uint)(value[j++] << 16) | - (uint)(value[j++] << 24); + _data[i] = (uint) value[j++] | + (uint) (value[j++] << 8) | + (uint) (value[j++] << 16) | + (uint) (value[j++] << 24); } size = len & 0x3; if (size > 0) @@ -357,10 +460,10 @@ namespace Renci.SshNet.Common for (var i = 0; i < fullWords; ++i) { - word = (uint)value[j++] | - (uint)(value[j++] << 8) | - (uint)(value[j++] << 16) | - (uint)(value[j++] << 24); + word = (uint) value[j++] | + (uint) (value[j++] << 8) | + (uint) (value[j++] << 16) | + (uint) (value[j++] << 24); sub = (ulong)word - borrow; word = (uint)sub; @@ -383,116 +486,340 @@ namespace Renci.SshNet.Common word = (uint)sub; borrow = (uint)(sub >> 32) & 0x1u; - _data[_data.Length - 1] = ~word & storeMask; + if ((~word & storeMask) == 0) + _data = Resize(_data, _data.Length - 1); + else + _data[_data.Length - 1] = ~word & storeMask; } if (borrow != 0) //FIXME I believe this can't happen, can someone write a test for it? throw new Exception("non zero final carry"); } } - #endregion - - #region Operators - /// - /// Defines an explicit conversion of a System.Numerics.BigInteger object to a 32-bit signed integer value. + /// Indicates whether the value of the current object is an even number. /// - /// The value to convert to a 32-bit signed integer. - /// - /// An object that contains the value of the value parameter. - /// - public static explicit operator int(BigInteger value) + /// + /// true if the value of the BigInteger object is an even number; otherwise, false. + /// + public bool IsEven { - int r; - if (!value.AsInt32(out r)) - throw new OverflowException(); - return r; + get { return _sign == 0 || (_data[0] & 0x1) == 0; } } /// - /// Defines an explicit conversion of a System.Numerics.BigInteger object to an unsigned 32-bit integer value. + /// Indicates whether the value of the current object is . + /// + /// + /// true if the value of the object is ; + /// otherwise, false. + /// + public bool IsOne + { + get { return _sign == 1 && _data.Length == 1 && _data[0] == 1; } + } + + + //Gem from Hacker's Delight + //Returns the number of bits set in @x + static int PopulationCount(uint x) + { + x = x - ((x >> 1) & 0x55555555); + x = (x & 0x33333333) + ((x >> 2) & 0x33333333); + x = (x + (x >> 4)) & 0x0F0F0F0F; + x = x + (x >> 8); + x = x + (x >> 16); + return (int)(x & 0x0000003F); + } + + //Based on code by Zilong Tan on Ulib released under MIT license + //Returns the number of bits set in @x + static int PopulationCount(ulong x) + { + x -= (x >> 1) & 0x5555555555555555UL; + x = (x & 0x3333333333333333UL) + ((x >> 2) & 0x3333333333333333UL); + x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0fUL; + return (int)((x * 0x0101010101010101UL) >> 56); + } + + static int LeadingZeroCount(uint value) + { + value |= value >> 1; + value |= value >> 2; + value |= value >> 4; + value |= value >> 8; + value |= value >> 16; + return 32 - PopulationCount(value); // 32 = bits in uint + } + + static int LeadingZeroCount(ulong value) + { + value |= value >> 1; + value |= value >> 2; + value |= value >> 4; + value |= value >> 8; + value |= value >> 16; + value |= value >> 32; + return 64 - PopulationCount(value); // 64 = bits in ulong + } + + static double BuildDouble(int sign, ulong mantissa, int exponent) + { + const int exponentBias = 1023; + const int mantissaLength = 52; + const int exponentLength = 11; + const int maxExponent = 2046; + const long mantissaMask = 0xfffffffffffffL; + const long exponentMask = 0x7ffL; + const ulong negativeMark = 0x8000000000000000uL; + + if (sign == 0 || mantissa == 0) + { + return 0.0; + } + + exponent += exponentBias + mantissaLength; + var offset = LeadingZeroCount(mantissa) - exponentLength; + if (exponent - offset > maxExponent) + { + return sign > 0 ? double.PositiveInfinity : double.NegativeInfinity; + } + if (offset < 0) + { + mantissa >>= -offset; + exponent += -offset; + } + else if (offset >= exponent) + { + mantissa <<= exponent - 1; + exponent = 0; + } + else + { + mantissa <<= offset; + exponent -= offset; + } + mantissa = mantissa & mantissaMask; + if ((exponent & exponentMask) == exponent) + { + unchecked + { + var bits = mantissa | ((ulong)exponent << mantissaLength); + if (sign < 0) + { + bits |= negativeMark; + } + return BitConverter.Int64BitsToDouble((long)bits); + } + } + return sign > 0 ? double.PositiveInfinity : double.NegativeInfinity; + } + + /// + /// Indicates whether the value of the current object is a power of two. + /// + /// + /// true if the value of the object is a power of two; + /// otherwise, false. + /// + public bool IsPowerOfTwo + { + get + { + var foundBit = false; + if (_sign != 1) + return false; + //This function is pop count == 1 for positive numbers + foreach (var bit in _data) + { + var p = PopulationCount(bit); + if (p > 0) + { + if (p > 1 || foundBit) + return false; + foundBit = true; + } + } + return foundBit; + } + } + + /// + /// Indicates whether the value of the current object is . + /// + /// + /// true if the value of the object is ; + /// otherwise, false. + /// + public bool IsZero + { + get { return _sign == 0; } + } + + /// + /// Gets a number that indicates the sign (negative, positive, or zero) of the current object. + /// + /// + /// A number that indicates the sign of the object. + /// + public int Sign + { + get { return _sign; } + } + + /// + /// Gets a value that represents the number negative one (-1). + /// + /// + /// An integer whose value is negative one (-1). + /// + public static BigInteger MinusOne + { + get { return MinusOneSingleton; } + } + + /// + /// Gets a value that represents the number one (1). + /// + /// + /// An object whose value is one (1). + /// + public static BigInteger One + { + get { return OneSingleton; } + } + + /// + /// Gets a value that represents the number 0 (zero). + /// + /// + /// An integer whose value is 0 (zero). + /// + public static BigInteger Zero + { + get { return ZeroSingleton; } + } + + /// + /// Defines an explicit conversion of a object to a 32-bit signed integer value. + /// + /// The value to convert to a 32-bit signed integer. + /// + /// An object that contains the value of the parameter. + /// + public static explicit operator int(BigInteger value) + { + if (value._data == null) + return 0; + if (value._data.Length > 1) + throw new OverflowException(); + var data = value._data[0]; + + if (value._sign == 1) + { + if (data > (uint)int.MaxValue) + throw new OverflowException(); + return (int)data; + } + if (value._sign == -1) + { + if (data > 0x80000000u) + throw new OverflowException(); + return -(int)data; + } + + return 0; + } + + /// + /// Defines an explicit conversion of a object to an unsigned 32-bit integer value. /// /// The value to convert to an unsigned 32-bit integer. /// - /// An object that contains the value of the value parameter. + /// An object that contains the value of the parameter. /// + [CLSCompliant(false)] public static explicit operator uint(BigInteger value) { + if (value._data == null) + return 0; if (value._data.Length > 1 || value._sign == -1) throw new OverflowException(); return value._data[0]; } /// - /// Defines an explicit conversion of a System.Numerics.BigInteger object to a 16-bit signed integer value. + /// Defines an explicit conversion of a object to a 16-bit signed integer value. /// /// The value to convert to a 16-bit signed integer. /// - /// An object that contains the value of the value parameter. + /// An object that contains the value of the parameter. /// public static explicit operator short(BigInteger value) { - int val = (int)value; + var val = (int)value; if (val < short.MinValue || val > short.MaxValue) throw new OverflowException(); return (short)val; } /// - /// Defines an explicit conversion of a System.Numerics.BigInteger object to an unsigned 16-bit integer value. + /// /// - /// The value to convert to an unsigned 16-bit integer. + /// /// - /// An object that contains the value of the value parameter + /// An object that contains the value of the parameter. /// + [CLSCompliantAttribute(false)] public static explicit operator ushort(BigInteger value) { - var val = (uint) value; + var val = (uint)value; if (val > ushort.MaxValue) throw new OverflowException(); - return (ushort) val; + return (ushort)val; } /// - /// Defines an explicit conversion of a System.Numerics.BigInteger object to an unsigned byte value. + /// Defines an explicit conversion of a object to an unsigned byte value. /// - /// The value to convert to a System.Byte. + /// The value to convert to a . /// - /// An object that contains the value of the value parameter. + /// An object that contains the value of the parameter. /// public static explicit operator byte(BigInteger value) { - var val = (uint) value; + var val = (uint)value; if (val > byte.MaxValue) throw new OverflowException(); - return (byte) val; + return (byte)val; } /// - /// Defines an explicit conversion of a System.Numerics.BigInteger object to a signed 8-bit value. + /// Defines an explicit conversion of a object to a signed 8-bit value. /// /// The value to convert to a signed 8-bit value. /// - /// An object that contains the value of the value parameter. + /// An object that contains the value of the parameter. /// + [CLSCompliant(false)] public static explicit operator sbyte(BigInteger value) { - var val = (int) value; + var val = (int)value; if (val < sbyte.MinValue || val > sbyte.MaxValue) throw new OverflowException(); - return (sbyte) val; + return (sbyte)val; } /// - /// Defines an explicit conversion of a System.Numerics.BigInteger object to a 64-bit signed integer value. + /// Defines an explicit conversion of a object to a 64-bit signed integer value. /// /// The value to convert to a 64-bit signed integer. /// - /// An object that contains the value of the value parameter. + /// An object that contains the value of the parameter. /// public static explicit operator long(BigInteger value) { - if (value._sign == 0) + if (value._data == null) return 0; if (value._data.Length > 2) @@ -504,7 +831,7 @@ namespace Renci.SshNet.Common { if (value._sign == 1) return (long)low; - long res = (long)low; + var res = (long)low; return -res; } @@ -517,21 +844,34 @@ namespace Renci.SshNet.Common return (((long)high) << 32) | low; } - if (high > 0x80000000u) - throw new OverflowException(); + /* + We cannot represent negative numbers smaller than long.MinValue. + Those values are encoded into what look negative numbers, so negating + them produces a positive value, that's why it's safe to check for that + condition. - return -((((long)high) << 32) | (long)low); + long.MinValue works fine since it's bigint encoding looks like a negative + number, but since long.MinValue == -long.MinValue, we're good. + */ + + var result = -((((long)high) << 32) | (long)low); + if (result > 0) + throw new OverflowException(); + return result; } /// - /// Defines an explicit conversion of a System.Numerics.BigInteger object to an unsigned 64-bit integer value. + /// Defines an explicit conversion of a object to an unsigned 64-bit integer value. /// /// The value to convert to an unsigned 64-bit integer. /// - /// An object that contains the value of the value parameter. + /// An object that contains the value of the parameter. /// + [CLSCompliant(false)] public static explicit operator ulong(BigInteger value) { + if (value._data == null) + return 0; if (value._data.Length > 2 || value._sign == -1) throw new OverflowException(); @@ -544,57 +884,63 @@ namespace Renci.SshNet.Common } /// - /// Defines an explicit conversion of a System.Numerics.BigInteger object to a value. + /// Defines an explicit conversion of a object to a value. /// - /// The value to convert to a . + /// The value to convert to a . /// - /// An object that contains the value of the value parameter. + /// An object that contains the value of the parameter. /// public static explicit operator double(BigInteger value) { - //FIXME - try + if (value._data == null) + return 0.0; + + switch (value._data.Length) { - return double.Parse(value.ToString(), - CultureInfo.InvariantCulture.NumberFormat); - } - catch (OverflowException) - { - return value._sign == -1 ? double.NegativeInfinity : double.PositiveInfinity; + case 1: + return BuildDouble(value._sign, value._data[0], 0); + case 2: + return BuildDouble(value._sign, (ulong)value._data[1] << 32 | (ulong)value._data[0], 0); + default: + var index = value._data.Length - 1; + var word = value._data[index]; + var mantissa = ((ulong)word << 32) | value._data[index - 1]; + var missing = LeadingZeroCount(word) - 11; // 11 = bits in exponent + if (missing > 0) + { + // add the missing bits from the next word + mantissa = (mantissa << missing) | (value._data[index - 2] >> (32 - missing)); + } + else + { + mantissa >>= -missing; + } + return BuildDouble(value._sign, mantissa, ((value._data.Length - 2) * 32) - missing); } } /// - /// Defines an explicit conversion of a System.Numerics.BigInteger object to a single-precision floating-point value. + /// Defines an explicit conversion of a object to a single-precision floating-point value. /// /// The value to convert to a single-precision floating-point value. /// - /// An object that contains the closest possible representation of the value parameter. + /// An object that contains the value of the parameter. /// public static explicit operator float(BigInteger value) { - //FIXME - try - { - return float.Parse(value.ToString(), - CultureInfo.InvariantCulture.NumberFormat); - } - catch (OverflowException) - { - return value._sign == -1 ? float.NegativeInfinity : float.PositiveInfinity; - } + return (float)(double)value; } /// - /// Defines an explicit conversion of a System.Numerics.BigInteger object to a value. + /// Defines an explicit conversion of a object to a value. /// - /// The value to convert to a . + /// The value to convert to a . /// - /// An object that contains the value of the value parameter. + /// An object that contains the value of the parameter. /// public static explicit operator decimal(BigInteger value) { - if (value._sign == 0) + if (value._data == null) return decimal.Zero; var data = value._data; @@ -603,21 +949,21 @@ namespace Renci.SshNet.Common int lo = 0, mi = 0, hi = 0; if (data.Length > 2) - hi = (int) data[2]; + hi = (int)data[2]; if (data.Length > 1) - mi = (int) data[1]; + mi = (int)data[1]; if (data.Length > 0) - lo = (int) data[0]; + lo = (int)data[0]; return new decimal(lo, mi, hi, value._sign < 0, 0); } /// - /// Defines an implicit conversion of a signed 32-bit integer to a System.Numerics.BigInteger value. + /// Defines an implicit conversion of a signed 32-bit integer to a value. /// - /// The value to convert to a System.Numerics.BigInteger. + /// The value to convert to a . /// - /// An object that contains the value of the value parameter. + /// An object that contains the value of the parameter. /// public static implicit operator BigInteger(int value) { @@ -625,23 +971,24 @@ namespace Renci.SshNet.Common } /// - /// Defines an implicit conversion of a 32-bit unsigned integer to a System.Numerics.BigInteger value. + /// Defines an implicit conversion of a 32-bit unsigned integer to a value. /// - /// The value to convert to a System.Numerics.BigInteger. + /// The value to convert to a . /// - /// An object that contains the value of the value parameter. + /// An object that contains the value of the parameter. /// + [CLSCompliant(false)] public static implicit operator BigInteger(uint value) { return new BigInteger(value); } /// - /// Defines an implicit conversion of a signed 16-bit integer to a System.Numerics.BigInteger value. + /// Defines an implicit conversion of a signed 16-bit integer to a BigInteger value. /// - /// The value to convert to a System.Numerics.BigInteger. + /// The value to convert to a . /// - /// An object that contains the value of the value parameter. + /// An object that contains the value of the parameter. /// public static implicit operator BigInteger(short value) { @@ -649,23 +996,24 @@ namespace Renci.SshNet.Common } /// - /// Defines an implicit conversion of a 16-bit unsigned integer to a System.Numerics.BigInteger value. + /// Defines an implicit conversion of a 16-bit unsigned integer to a value. /// - /// The value to convert to a System.Numerics.BigInteger. + /// The value to convert to a . /// - /// An object that contains the value of the value parameter. + /// An object that contains the value of the parameter. /// + [CLSCompliantAttribute(false)] public static implicit operator BigInteger(ushort value) { return new BigInteger(value); } /// - /// Defines an implicit conversion of an unsigned byte to a System.Numerics.BigInteger value. + /// Defines an implicit conversion of an unsigned byte to a value. /// - /// The value to convert to a System.Numerics.BigInteger. + /// The value to convert to a . /// - /// An object that contains the value of the value parameter. + /// An object that contains the value of the parameter. /// public static implicit operator BigInteger(byte value) { @@ -673,23 +1021,24 @@ namespace Renci.SshNet.Common } /// - /// Defines an implicit conversion of an 8-bit signed integer to a System.Numerics.BigInteger value. + /// /// - /// The value to convert to a System.Numerics.BigInteger. + /// The value to convert to a . /// - /// An object that contains the value of the value parameter. + /// An object that contains the value of the parameter. /// + [CLSCompliant(false)] public static implicit operator BigInteger(sbyte value) { return new BigInteger(value); } /// - /// Defines an implicit conversion of a signed 64-bit integer to a System.Numerics.BigInteger value. + /// Defines an implicit conversion of a signed 64-bit integer to a value. /// - /// The value to convert to a System.Numerics.BigInteger. + /// The value to convert to a . /// - /// An object that contains the value of the value parameter. + /// An object that contains the value of the parameter. /// public static implicit operator BigInteger(long value) { @@ -697,23 +1046,24 @@ namespace Renci.SshNet.Common } /// - /// Defines an implicit conversion of a 64-bit unsigned integer to a System.Numerics.BigInteger value. + /// Defines an implicit conversion of a 64-bit unsigned integer to a value. /// - /// The value to convert to a System.Numerics.BigInteger. + /// The value to convert to a . /// - /// An object that contains the value of the value parameter. + /// An object that contains the value of the parameter. /// + [CLSCompliant(false)] public static implicit operator BigInteger(ulong value) { return new BigInteger(value); } /// - /// Defines an explicit conversion of a value to a System.Numerics.BigInteger value. + /// Defines an explicit conversion of a value to a value. /// - /// The value to convert to a System.Numerics.BigInteger. + /// The value to convert to a . /// - /// An object that contains the value of the value parameter. + /// An object that contains the value of the parameter. /// public static explicit operator BigInteger(double value) { @@ -721,11 +1071,11 @@ namespace Renci.SshNet.Common } /// - /// Defines an explicit conversion of a object to a System.Numerics.BigInteger value. + /// Defines an explicit conversion of a object to a value. /// - /// The value to convert to a System.Numerics.BigInteger. + /// The value to convert to a . /// - /// An object that contains the value of the value parameter. + /// An object that contains the value of the parameter. /// public static explicit operator BigInteger(float value) { @@ -733,11 +1083,11 @@ namespace Renci.SshNet.Common } /// - /// Defines an explicit conversion of a object to a System.Numerics.BigInteger value. + /// Defines an explicit conversion of a object to a value. /// - /// The value to convert to a System.Numerics.BigInteger. + /// The value to convert to a . /// - /// An object that contains the value of the value parameter. + /// An object that contains the value of the parameter. /// public static explicit operator BigInteger(decimal value) { @@ -750,7 +1100,7 @@ namespace Renci.SshNet.Common /// The first value to add. /// The second value to add. /// - /// The sum of left and right. + /// The sum of and . /// public static BigInteger operator +(BigInteger left, BigInteger right) { @@ -762,10 +1112,10 @@ namespace Renci.SshNet.Common if (left._sign == right._sign) return new BigInteger(left._sign, CoreAdd(left._data, right._data)); - int r = CoreCompare(left._data, right._data); + var r = CoreCompare(left._data, right._data); if (r == 0) - return new BigInteger(0, _zero); + return Zero; if (r > 0) //left > right return new BigInteger(left._sign, CoreSub(left._data, right._data)); @@ -779,7 +1129,7 @@ namespace Renci.SshNet.Common /// The value to subtract from (the minuend). /// The value to subtract (the subtrahend). /// - /// The result of subtracting right from left. + /// The result of subtracting from . /// public static BigInteger operator -(BigInteger left, BigInteger right) { @@ -790,10 +1140,10 @@ namespace Renci.SshNet.Common if (left._sign == right._sign) { - int r = CoreCompare(left._data, right._data); + var r = CoreCompare(left._data, right._data); if (r == 0) - return new BigInteger(0, _zero); + return Zero; if (r > 0) //left > right return new BigInteger(left._sign, CoreSub(left._data, right._data)); @@ -815,7 +1165,7 @@ namespace Renci.SshNet.Common public static BigInteger operator *(BigInteger left, BigInteger right) { if (left._sign == 0 || right._sign == 0) - return new BigInteger(0, _zero); + return Zero; if (left._data[0] == 1 && left._data.Length == 1) { @@ -862,11 +1212,12 @@ namespace Renci.SshNet.Common if (m < res.Length - 1) res = Resize(res, m + 1); - return new BigInteger((short)(left._sign * right._sign), res); + return new BigInteger((short) (left._sign*right._sign), res); } /// - /// Divides a specified value by another specified value by using integer division. + /// Divides a specified value by another specified value by using + /// integer division. /// /// The value to be divided. /// The value to divide by. @@ -889,11 +1240,11 @@ namespace Renci.SshNet.Common int i; for (i = quotient.Length - 1; i >= 0 && quotient[i] == 0; --i) ; if (i == -1) - return new BigInteger(0, _zero); + return Zero; if (i < quotient.Length - 1) quotient = Resize(quotient, i + 1); - return new BigInteger((short) (dividend._sign*divisor._sign), quotient); + return new BigInteger((short)(dividend._sign * divisor._sign), quotient); } /// @@ -920,7 +1271,7 @@ namespace Renci.SshNet.Common int i; for (i = remainderValue.Length - 1; i >= 0 && remainderValue[i] == 0; --i) ; if (i == -1) - return new BigInteger(0, _zero); + return Zero; if (i < remainderValue.Length - 1) remainderValue = Resize(remainderValue, i + 1); @@ -928,26 +1279,29 @@ namespace Renci.SshNet.Common } /// - /// Negates a specified BigInteger value. + /// Negates a specified value. /// /// The value to negate. - /// - /// The result of the value parameter multiplied by negative one (-1). + /// + /// The result of the parameter multiplied by negative one (-1). /// public static BigInteger operator -(BigInteger value) { - if (value._sign == 0) + if (value._data == null) return value; return new BigInteger((short)-value._sign, value._data); } /// - /// Returns the value of the operand. (The sign of the operand is unchanged.) + /// Returns the value of the operand. /// /// An integer value. /// - /// The value of the value operand. + /// The value of the operand. /// + /// + /// The sign of the operand is unchanged. + /// public static BigInteger operator +(BigInteger value) { return value; @@ -958,24 +1312,24 @@ namespace Renci.SshNet.Common /// /// The value to increment. /// - /// The value of the value parameter incremented by 1. + /// The value of the parameter incremented by 1. /// public static BigInteger operator ++(BigInteger value) { + if (value._data == null) + return One; + var sign = value._sign; var data = value._data; if (data.Length == 1) { if (sign == -1 && data[0] == 1) - return new BigInteger(0, _zero); + return Zero; if (sign == 0) - return new BigInteger(1, _one); + return One; } - if (sign == -1) - data = CoreSub(data, 1); - else - data = CoreAdd(data, 1); + data = sign == -1 ? CoreSub(data, 1) : CoreAdd(data, 1); return new BigInteger(sign, data); } @@ -985,35 +1339,35 @@ namespace Renci.SshNet.Common /// /// The value to decrement. /// - /// The value of the value parameter decremented by 1. + /// The value of the parameter decremented by 1. /// public static BigInteger operator --(BigInteger value) { + if (value._data == null) + return MinusOne; + var sign = value._sign; var data = value._data; if (data.Length == 1) { if (sign == 1 && data[0] == 1) - return new BigInteger(0, _zero); + return Zero; if (sign == 0) - return new BigInteger(-1, _one); + return MinusOne; } - if (sign == -1) - data = CoreAdd(data, 1); - else - data = CoreSub(data, 1); + data = sign == -1 ? CoreAdd(data, 1) : CoreSub(data, 1); return new BigInteger(sign, data); } /// - /// Performs a bitwise And operation on two values. + /// Performs a bitwise And operation on two values. /// /// The first value. /// The second value. /// - /// The result of the bitwise And operation. + /// The result of the bitwise And operation. /// public static BigInteger operator &(BigInteger left, BigInteger right) { @@ -1028,7 +1382,7 @@ namespace Renci.SshNet.Common int ls = left._sign; int rs = right._sign; - bool neg_res = (ls == rs) && (ls == -1); + var negRes = (ls == rs) && (ls == -1); var result = new uint[Math.Max(a.Length, b.Length)]; @@ -1057,9 +1411,9 @@ namespace Renci.SshNet.Common bc = (uint)(bc >> 32); } - uint word = va & vb; + var word = va & vb; - if (neg_res) + if (negRes) { borrow = word - borrow; word = ~(uint)borrow; @@ -1071,21 +1425,21 @@ namespace Renci.SshNet.Common for (i = result.Length - 1; i >= 0 && result[i] == 0; --i) ; if (i == -1) - return new BigInteger(0, _zero); + return Zero; if (i < result.Length - 1) result = Resize(result, i + 1); - return new BigInteger(neg_res ? (short)-1 : (short)1, result); + return new BigInteger(negRes ? (short)-1 : (short)1, result); } /// - /// Performs a bitwise Or operation on two values. + /// Performs a bitwise Or operation on two values. /// /// The first value. /// The second value. /// - /// The result of the bitwise Or operation. + /// The result of the bitwise Or operation. /// public static BigInteger operator |(BigInteger left, BigInteger right) { @@ -1100,7 +1454,7 @@ namespace Renci.SshNet.Common int ls = left._sign; int rs = right._sign; - bool neg_res = (ls == -1) || (rs == -1); + var negRes = (ls == -1) || (rs == -1); var result = new uint[Math.Max(a.Length, b.Length)]; @@ -1129,9 +1483,9 @@ namespace Renci.SshNet.Common bc = (uint)(bc >> 32); } - uint word = va | vb; + var word = va | vb; - if (neg_res) + if (negRes) { borrow = word - borrow; word = ~(uint)borrow; @@ -1143,21 +1497,21 @@ namespace Renci.SshNet.Common for (i = result.Length - 1; i >= 0 && result[i] == 0; --i) ; if (i == -1) - return new BigInteger(0, _zero); + return Zero; if (i < result.Length - 1) result = Resize(result, i + 1); - return new BigInteger(neg_res ? (short)-1 : (short)1, result); + return new BigInteger(negRes ? (short)-1 : (short)1, result); } /// - /// Performs a bitwise exclusive Or (XOr) operation on two values. + /// Performs a bitwise exclusive Or (XOr) operation on two values. /// /// The first value. /// The second value. /// - /// The result of the bitwise Or operation. + /// The result of the bitwise Or operation. /// public static BigInteger operator ^(BigInteger left, BigInteger right) { @@ -1172,7 +1526,7 @@ namespace Renci.SshNet.Common int ls = left._sign; int rs = right._sign; - bool neg_res = (ls == -1) ^ (rs == -1); + var negRes = (ls == -1) ^ (rs == -1); var result = new uint[Math.Max(a.Length, b.Length)]; @@ -1201,9 +1555,9 @@ namespace Renci.SshNet.Common bc = (uint)(bc >> 32); } - uint word = va ^ vb; + var word = va ^ vb; - if (neg_res) + if (negRes) { borrow = word - borrow; word = ~(uint)borrow; @@ -1215,12 +1569,12 @@ namespace Renci.SshNet.Common for (i = result.Length - 1; i >= 0 && result[i] == 0; --i) ; if (i == -1) - return new BigInteger(0, _zero); + return Zero; if (i < result.Length - 1) result = Resize(result, i + 1); - return new BigInteger(neg_res ? (short)-1 : (short)1, result); + return new BigInteger(negRes ? (short)-1 : (short)1, result); } /// @@ -1228,17 +1582,17 @@ namespace Renci.SshNet.Common /// /// An integer value. /// - /// The bitwise one's complement of value. + /// The bitwise one's complement of . /// public static BigInteger operator ~(BigInteger value) { - if (value._sign == 0) - return new BigInteger(-1, _one); + if (value._data == null) + return MinusOne; var data = value._data; int sign = value._sign; - bool neg_res = sign == 1; + var negRes = sign == 1; var result = new uint[data.Length]; @@ -1257,7 +1611,7 @@ namespace Renci.SshNet.Common word = ~word; - if (neg_res) + if (negRes) { borrow = word - borrow; word = ~(uint)borrow; @@ -1269,12 +1623,25 @@ namespace Renci.SshNet.Common for (i = result.Length - 1; i >= 0 && result[i] == 0; --i) ; if (i == -1) - return new BigInteger(0, _zero); + return Zero; if (i < result.Length - 1) result = Resize(result, i + 1); - return new BigInteger(neg_res ? (short)-1 : (short)1, result); + return new BigInteger(negRes ? (short)-1 : (short)1, result); + } + + //returns the 0-based index of the most significant set bit + //returns 0 if no bit is set, so extra care when using it + static int BitScanBackward(uint word) + { + for (var i = 31; i >= 0; --i) + { + var mask = 1u << i; + if ((word & mask) == mask) + return i; + } + return 0; } /// @@ -1287,7 +1654,7 @@ namespace Renci.SshNet.Common /// public static BigInteger operator <<(BigInteger value, int shift) { - if (shift == 0 || value._sign == 0) + if (shift == 0 || value._data == null) return value; if (shift < 0) return value >> -shift; @@ -1305,19 +1672,30 @@ namespace Renci.SshNet.Common var bitShift = shift & 0x1F; var carryShift = 32 - bitShift; - for (var i = 0; i < data.Length; ++i) + if (carryShift == 32) { - var word = data[i]; - res[i + idxShift] |= word << bitShift; - if (i + idxShift + 1 < res.Length) - res[i + idxShift + 1] = word >> carryShift; + for (var i = 0; i < data.Length; ++i) + { + var word = data[i]; + res[i + idxShift] |= word << bitShift; + } + } + else + { + for (var i = 0; i < data.Length; ++i) + { + var word = data[i]; + res[i + idxShift] |= word << bitShift; + if (i + idxShift + 1 < res.Length) + res[i + idxShift + 1] = word >> carryShift; + } } return new BigInteger((short)sign, res); } /// - /// Shifts a System.Numerics.BigInteger value a specified number of bits to the right. + /// Shifts a value a specified number of bits to the right. /// /// The value whose bits are to be shifted. /// The number of bits to shift value to the right. @@ -1335,38 +1713,52 @@ namespace Renci.SshNet.Common int sign = value._sign; var topMostIdx = BitScanBackward(data[data.Length - 1]); - var idx_shift = shift >> 5; - var bit_shift = shift & 0x1F; + var idxShift = shift >> 5; + var bitShift = shift & 0x1F; - var extra_words = idx_shift; - if (bit_shift > topMostIdx) - ++extra_words; - var size = data.Length - extra_words; + var extraWords = idxShift; + if (bitShift > topMostIdx) + ++extraWords; + var size = data.Length - extraWords; if (size <= 0) { if (sign == 1) - return new BigInteger(0, _zero); - return new BigInteger(-1, _one); + return Zero; + return MinusOne; } var res = new uint[size]; - var carryShift = 32 - bit_shift; + var carryShift = 32 - bitShift; - for (var i = data.Length - 1; i >= idx_shift; --i) + if (carryShift == 32) { - var word = data[i]; + for (var i = data.Length - 1; i >= idxShift; --i) + { + var word = data[i]; + + if (i - idxShift < res.Length) + res[i - idxShift] |= word >> bitShift; + } + } + else + { + for (var i = data.Length - 1; i >= idxShift; --i) + { + var word = data[i]; + + if (i - idxShift < res.Length) + res[i - idxShift] |= word >> bitShift; + if (i - idxShift - 1 >= 0) + res[i - idxShift - 1] = word << carryShift; + } - if (i - idx_shift < res.Length) - res[i - idx_shift] |= word >> bit_shift; - if (i - idx_shift - 1 >= 0) - res[i - idx_shift - 1] = word << carryShift; } //Round down instead of toward zero if (sign == -1) { - for (var i = 0; i < idx_shift; i++) + for (var i = 0; i < idxShift; i++) { if (data[i] != 0u) { @@ -1375,7 +1767,7 @@ namespace Renci.SshNet.Common return tmp; } } - if (bit_shift > 0 && (data[idx_shift] << carryShift) != 0u) + if (bitShift > 0 && (data[idxShift] << carryShift) != 0u) { var tmp = new BigInteger((short)sign, res); --tmp; @@ -1386,12 +1778,13 @@ namespace Renci.SshNet.Common } /// - /// Returns a value that indicates whether a value is less than another value. + /// Returns a value that indicates whether a value is less than another + /// value. /// /// The first value to compare. /// The second value to compare. /// - /// true if left is less than right; otherwise, false. + /// true if is less than ; otherwise, false. /// public static bool operator <(BigInteger left, BigInteger right) { @@ -1404,34 +1797,38 @@ namespace Renci.SshNet.Common /// The first value to compare. /// The second value to compare. /// - /// true if left is less than right; otherwise, false. + /// true if left is than ; otherwise, false. /// public static bool operator <(BigInteger left, long right) { return left.CompareTo(right) < 0; } + /// /// Returns a value that indicates whether a 64-bit signed integer is less than a value. /// /// The first value to compare. /// The second value to compare. /// - /// true if left is less than right; otherwise, false. + /// true if is less than ; + /// otherwise, false. /// public static bool operator <(long left, BigInteger right) { return right.CompareTo(left) > 0; } + /// - /// Returns a value that indicates whether a value is less than a 64-bit unsigned integer. + /// Returns a value that indicates whether a 64-bit signed integer is less than a value. /// /// The first value to compare. /// The second value to compare. /// - /// true if left is less than right; otherwise, false. + /// true if is less than ; otherwise, false. /// + [CLSCompliant(false)] public static bool operator <(BigInteger left, ulong right) { return left.CompareTo(right) < 0; @@ -1443,20 +1840,23 @@ namespace Renci.SshNet.Common /// The first value to compare. /// The second value to compare. /// - /// true if left is less than right; otherwise, false. + /// true if is less than ; otherwise, false. /// + [CLSCompliant(false)] public static bool operator <(ulong left, BigInteger right) { return right.CompareTo(left) > 0; } /// - /// Returns a value that indicates whether a System.Numerics.BigInteger value is less than or equal to another System.Numerics.BigInteger value. + /// Returns a value that indicates whether a value is less than or equal + /// to another value. /// /// The first value to compare. /// The second value to compare. /// - /// true if left is less than or equal to right; otherwise, false. + /// true if is less than or equal to ; + /// otherwise, false. /// public static bool operator <=(BigInteger left, BigInteger right) { @@ -1464,12 +1864,14 @@ namespace Renci.SshNet.Common } /// - /// Returns a value that indicates whether a System.Numerics.BigInteger value is less than or equal to a 64-bit signed integer. + /// Returns a value that indicates whether a value is less than or equal + /// to a 64-bit signed integer. /// /// The first value to compare. /// The second value to compare. /// - /// true if left is less than or equal to right; otherwise, false. + /// true if is less than or equal to ; + /// otherwise, false. /// public static bool operator <=(BigInteger left, long right) { @@ -1477,12 +1879,13 @@ namespace Renci.SshNet.Common } /// - /// Returns a value that indicates whether a 64-bit signed integer is less than or equal to a System.Numerics.BigInteger value. + /// Returns a value that indicates whether a 64-bit signed integer is less than or equal to a value. /// /// The first value to compare. /// The second value to compare. /// - /// true if left is less than or equal to right; otherwise, false. + /// true if is less than or equal to ; + /// otherwise, false. /// public static bool operator <=(long left, BigInteger right) { @@ -1490,38 +1893,46 @@ namespace Renci.SshNet.Common } /// - /// Returns a value that indicates whether a System.Numerics.BigInteger value is less than or equal to a 64-bit unsigned integer. + /// Returns a value that indicates whether a value is less than or equal to + /// a 64-bit unsigned integer. /// /// The first value to compare. /// The second value to compare. /// - /// true if left is less than or equal to right; otherwise, false. + /// true if is less than or equal to ; + /// otherwise, false. /// + [CLSCompliant(false)] public static bool operator <=(BigInteger left, ulong right) { return left.CompareTo(right) <= 0; } /// - /// Returns a value that indicates whether a 64-bit unsigned integer is less than or equal to a System.Numerics.BigInteger value. + /// Returns a value that indicates whether a 64-bit unsigned integer is less than or equal to a + /// value. /// /// The first value to compare. /// The second value to compare. /// - /// true if left is less than or equal to right; otherwise, false. + /// true if is less than or equal to ; + /// otherwise, false. /// + [CLSCompliant(false)] public static bool operator <=(ulong left, BigInteger right) { return right.CompareTo(left) >= 0; } /// - /// Returns a value that indicates whether a System.Numerics.BigInteger value is greater than another System.Numerics.BigInteger value. + /// Returns a value that indicates whether a value is greater than another + /// value. /// /// The first value to compare. /// The second value to compare. /// - /// true if left is greater than right; otherwise, false. + /// true if is greater than ; + /// otherwise, false. /// public static bool operator >(BigInteger left, BigInteger right) { @@ -1529,12 +1940,13 @@ namespace Renci.SshNet.Common } /// - /// Returns a value that indicates whether a System.Numerics.BigInteger is greater than a 64-bit signed integer value. + /// Returns a value that indicates whether a is greater than a 64-bit signed integer value. /// /// The first value to compare. /// The second value to compare. /// - /// true if left is greater than right; otherwise, false. + /// true if is greater than ; + /// otherwise, false. /// public static bool operator >(BigInteger left, long right) { @@ -1542,12 +1954,13 @@ namespace Renci.SshNet.Common } /// - /// Returns a value that indicates whether a 64-bit signed integer is greater than a System.Numerics.BigInteger value. + /// Returns a value that indicates whether a 64-bit signed integer is greater than a value. /// /// The first value to compare. /// The second value to compare. /// - /// true if left is greater than right; otherwise, false. + /// true if is greater than ; + /// otherwise, false. /// public static bool operator >(long left, BigInteger right) { @@ -1555,38 +1968,44 @@ namespace Renci.SshNet.Common } /// - /// Returns a value that indicates whether a System.Numerics.BigInteger value is greater than a 64-bit unsigned integer. + /// Returns a value that indicates whether a value is greater than a 64-bit unsigned integer. /// /// The first value to compare. /// The second value to compare. /// - /// true if left is greater than right; otherwise, false. + /// true if is greater than ; + /// otherwise, false. /// + [CLSCompliant(false)] public static bool operator >(BigInteger left, ulong right) { return left.CompareTo(right) > 0; } /// - /// Returns a value that indicates whether a System.Numerics.BigInteger value is greater than a 64-bit unsigned integer. + /// Returns a value that indicates whether a 64-bit unsigned integer is greater than a value. /// /// The first value to compare. /// The second value to compare. /// - /// true if left is greater than right; otherwise, false. + /// true if is greater than ; + /// otherwise, false. /// + [CLSCompliant(false)] public static bool operator >(ulong left, BigInteger right) { return right.CompareTo(left) < 0; } /// - /// Returns a value that indicates whether a System.Numerics.BigInteger value is greater than or equal to another System.Numerics.BigInteger value. + /// Returns a value that indicates whether a value is greater than or equal + /// to another value. /// /// The first value to compare. /// The second value to compare. /// - /// true if left is greater than or equal right; otherwise, false. + /// true if is greater than ; + /// otherwise, false. /// public static bool operator >=(BigInteger left, BigInteger right) { @@ -1594,12 +2013,14 @@ namespace Renci.SshNet.Common } /// - /// Returns a value that indicates whether a System.Numerics.BigInteger value is greater than or equal to a 64-bit signed integer value. + /// Returns a value that indicates whether a value is greater than or equal + /// to a 64-bit signed integer value. /// /// The first value to compare. /// The second value to compare. /// - /// true if left is greater than or equal right; otherwise, false. + /// true if is greater than ; + /// otherwise, false. /// public static bool operator >=(BigInteger left, long right) { @@ -1607,12 +2028,14 @@ namespace Renci.SshNet.Common } /// - /// Returns a value that indicates whether a 64-bit signed integer is greater than or equal to a System.Numerics.BigInteger value. + /// Returns a value that indicates whether a 64-bit signed integer is greater than or equal to a + /// value. /// /// The first value to compare. /// The second value to compare. /// - /// true if left is greater than or equal right; otherwise, false. + /// true if is greater than ; + /// otherwise, false. /// public static bool operator >=(long left, BigInteger right) { @@ -1620,38 +2043,45 @@ namespace Renci.SshNet.Common } /// - /// Returns a value that indicates whether a System.Numerics.BigInteger value is greater than or equal to a 64-bit unsigned integer value. + /// Returns a value that indicates whether a value is greater than or equal to a + /// 64-bit unsigned integer value. /// /// The first value to compare. /// The second value to compare. /// - /// true if left is greater than or equal right; otherwise, false. + /// true if is greater than ; + /// otherwise, false. /// + [CLSCompliant(false)] public static bool operator >=(BigInteger left, ulong right) { return left.CompareTo(right) >= 0; } /// - /// Returns a value that indicates whether a 64-bit unsigned integer is greater than or equal to a System.Numerics.BigInteger value. + /// Returns a value that indicates whether a 64-bit unsigned integer is greater than or equal to a + /// value. /// /// The first value to compare. /// The second value to compare. /// - /// true if left is greater than or equal right; otherwise, false. + /// true if is greater than ; + /// otherwise, false. /// + [CLSCompliant(false)] public static bool operator >=(ulong left, BigInteger right) { return right.CompareTo(left) <= 0; } /// - /// Returns a value that indicates whether the values of two System.Numerics.BigInteger objects are equal. + /// Returns a value that indicates whether the values of two objects are equal. /// /// The first value to compare. /// The second value to compare. /// - /// true if the left and right parameters have the same value; otherwise, false. + /// true if the and parameters have the same value; + /// otherwise, false. /// public static bool operator ==(BigInteger left, BigInteger right) { @@ -1659,12 +2089,13 @@ namespace Renci.SshNet.Common } /// - /// Returns a value that indicates whether a System.Numerics.BigInteger value and a signed long integer value are equal. + /// Returns a value that indicates whether a value and a signed long integer value are equal. /// /// The first value to compare. /// The second value to compare. /// - /// true if the left and right parameters have the same value; otherwise, false. + /// true if the and parameters have the same value; + /// otherwise, false. /// public static bool operator ==(BigInteger left, long right) { @@ -1672,12 +2103,13 @@ namespace Renci.SshNet.Common } /// - /// Returns a value that indicates whether a signed long integer value and a System.Numerics.BigInteger value are equal. + /// Returns a value that indicates whether a signed long integer value and a value are equal. /// /// The first value to compare. /// The second value to compare. /// - /// true if the left and right parameters have the same value; otherwise, false. + /// true if the and parameters have the same value; + /// otherwise, false. /// public static bool operator ==(long left, BigInteger right) { @@ -1685,26 +2117,30 @@ namespace Renci.SshNet.Common } /// - /// Returns a value that indicates whether a System.Numerics.BigInteger value and an unsigned long integer value are equal. + /// Returns a value that indicates whether a value and an unsigned long integer value are equal. /// /// The first value to compare. /// The second value to compare. /// - /// true if the left and right parameters have the same value; otherwise, false. + /// true if the and parameters have the same value; + /// otherwise, false. /// + [CLSCompliant(false)] public static bool operator ==(BigInteger left, ulong right) { return left.CompareTo(right) == 0; } /// - /// Returns a value that indicates whether an unsigned long integer value and a System.Numerics.BigInteger value are equal. + /// Returns a value that indicates whether an unsigned long integer value and a value are equal. /// /// The first value to compare. /// The second value to compare. /// - /// true if the left and right parameters have the same value; otherwise, false. + /// true if the and parameters have the same value; + /// otherwise, false. /// + [CLSCompliant(false)] public static bool operator ==(ulong left, BigInteger right) { return right.CompareTo(left) == 0; @@ -1716,7 +2152,8 @@ namespace Renci.SshNet.Common /// The first value to compare. /// The second value to compare. /// - /// true if left and right are not equal; otherwise, false. + /// true if and are not equal; + /// otherwise, false. /// public static bool operator !=(BigInteger left, BigInteger right) { @@ -1729,7 +2166,8 @@ namespace Renci.SshNet.Common /// The first value to compare. /// The second value to compare. /// - /// true if left and right are not equal; otherwise, false. + /// true if and are not equal; + /// otherwise, false. /// public static bool operator !=(BigInteger left, long right) { @@ -1742,7 +2180,8 @@ namespace Renci.SshNet.Common /// The first value to compare. /// The second value to compare. /// - /// true if left and right are not equal; otherwise, false. + /// true if and are not equal; + /// otherwise, false. /// public static bool operator !=(long left, BigInteger right) { @@ -1755,8 +2194,10 @@ namespace Renci.SshNet.Common /// The first value to compare. /// The second value to compare. /// - /// true if left and right are not equal; otherwise, false. + /// true if and are not equal; + /// otherwise, false. /// + [CLSCompliant(false)] public static bool operator !=(BigInteger left, ulong right) { return left.CompareTo(right) != 0; @@ -1768,224 +2209,982 @@ namespace Renci.SshNet.Common /// The first value to compare. /// The second value to compare. /// - /// true if left and right are not equal; otherwise, false. + /// true if and are not equal; + /// otherwise, false. /// + [CLSCompliant(false)] public static bool operator !=(ulong left, BigInteger right) { return right.CompareTo(left) != 0; } - #endregion - /// - /// Indicates whether the value of the current System.Numerics.BigInteger object is an even number. + /// Returns a value that indicates whether the current instance and a specified object have the same value. /// - /// - /// true if the value of the System.Numerics.BigInteger object is an even number; otherwise, false. - /// - public bool IsEven - { - get { return (_data[0] & 0x1) == 0; } - } - - /// - /// Indicates whether the value of the current System.Numerics.BigInteger object is System.Numerics.BigInteger.One. - /// - /// - /// true if the value of the System.Numerics.BigInteger object is System.Numerics.BigInteger.One; otherwise, false. - /// - public bool IsOne - { - get { return _sign == 1 && _data.Length == 1 && _data[0] == 1; } - } - - /// - /// Indicates whether the value of the current System.Numerics.BigInteger object is a power of two. - /// - /// - /// true if the value of the System.Numerics.BigInteger object is a power of two; otherwise, false. - /// - public bool IsPowerOfTwo - { - get - { - bool foundBit = false; - if (_sign != 1) - return false; - //This function is pop count == 1 for positive numbers - for (var i = 0; i < _data.Length; ++i) - { - var p = PopulationCount(_data[i]); - if (p > 0) - { - if (p > 1 || foundBit) - return false; - foundBit = true; - } - } - return foundBit; - } - } - - /// - /// Indicates whether the value of the current System.Numerics.BigInteger object is System.Numerics.BigInteger.Zero. - /// - /// - /// true if the value of the System.Numerics.BigInteger object is System.Numerics.BigInteger.Zero; otherwise, false. - /// - public bool IsZero - { - get { return _sign == 0; } - } - - /// - /// Gets a value that represents the number negative one (-1). - /// - public static BigInteger MinusOne - { - get { return new BigInteger(-1, _one); } - } - - /// - /// Gets a value that represents the number one (1). - /// - public static BigInteger One - { - get { return new BigInteger(1, _one); } - } - - /// - /// Gets a number that indicates the sign (negative, positive, or zero) of the current System.Numerics.BigInteger object. - /// - public int Sign - { - get { return _sign; } - } - - /// - /// Gets a value that represents the number 0 (zero). - /// - public static BigInteger Zero - { - get { return new BigInteger(0, _zero); } - } - - /// - /// Gets the absolute value of a System.Numerics.BigInteger object. - /// - /// A number. - /// The absolute value of value. - public static BigInteger Abs(BigInteger value) - { - return new BigInteger(Math.Abs(value._sign), value._data); - } - - /// - /// Adds two System.Numerics.BigInteger values and returns the result. - /// - /// The first value to add. - /// The second value to add. - /// The sum of left and right. - public static BigInteger Add(BigInteger left, BigInteger right) - { - return left + right; - } - - /// - /// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object. - /// - /// An object to compare with this instance. + /// The object to compare. /// - /// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than zero This instance is less than . Zero This instance is equal to . Greater than zero This instance is greater than . + /// true if the parameter is a object or a type capable + /// of implicit conversion to a value, and its value is equal to the value of the + /// current object; otherwise, false. /// - /// - /// is not the same type as this instance. - public int CompareTo(object obj) + public override bool Equals(object obj) { - if (obj == null) - return 1; - if (!(obj is BigInteger)) - return -1; - - return Compare(this, (BigInteger)obj); + return false; + return Equals((BigInteger)obj); } /// - /// Compares this instance to a second System.Numerics.BigInteger and returns - /// an integer that indicates whether the value of this instance is less than, - /// equal to, or greater than the value of the specified object. + /// Returns a value that indicates whether the current instance and a specified object + /// have the same value. /// /// The object to compare. /// - /// A signed integer value that indicates the relationship of this instance to - /// other, as shown in the following table.Return valueDescriptionLess than zeroThe - /// current instance is less than other.ZeroThe current instance equals other.Greater - /// than zeroThe current instance is greater than other. + /// true if this object and have the same value; + /// otherwise, false. /// - public int CompareTo(BigInteger other) + public bool Equals(BigInteger other) { - return Compare(this, other); + if (_sign != other._sign) + return false; + + var alen = _data != null ? _data.Length : 0; + var blen = other._data != null ? other._data.Length : 0; + + if (alen != blen) + return false; + for (var i = 0; i < alen; ++i) + { + if (_data[i] != other._data[i]) + return false; + } + return true; } /// - /// Compares this instance to an unsigned 64-bit integer and returns an integer - /// that indicates whether the value of this instance is less than, equal to, - /// or greater than the value of the unsigned 64-bit integer. + /// Returns a value that indicates whether the current instance and a signed 64-bit integer have the same value. /// - /// The unsigned 64-bit integer to compare. - /// A signed integer that indicates the relative value of this instance and other, - /// as shown in the following table.Return valueDescriptionLess than zeroThe - /// current instance is less than other.ZeroThe current instance equals other.Greater - /// than zeroThe current instance is greater than other. - public int CompareTo(ulong other) + /// The signed 64-bit integer value to compare. + /// + /// true if the signed 64-bit integer and the current instance have the same value; otherwise, false. + /// + public bool Equals(long other) { - if (_sign < 0) - return -1; + return CompareTo(other) == 0; + } + + /// + /// Converts the numeric value of the current object to its equivalent string representation. + /// + /// + /// The string representation of the current value. + /// + public override string ToString() + { + return ToString(10, null); + } + + private string ToStringWithPadding(string format, uint radix, IFormatProvider provider) + { + if (format.Length > 1) + { + var precision = Convert.ToInt32(format.Substring(1), CultureInfo.InvariantCulture.NumberFormat); + var baseStr = ToString(radix, provider); + if (baseStr.Length < precision) + { + var additional = new string('0', precision - baseStr.Length); + if (baseStr[0] != '-') + { + return additional + baseStr; + } + return "-" + additional + baseStr.Substring(1); + } + return baseStr; + } + return ToString(radix, provider); + } + + /// + /// Converts the numeric value of the current object to its equivalent string representation + /// by using the specified format. + /// + /// A standard or custom numeric format string. + /// + /// The string representation of the current value in the format specified by the + /// parameter. + /// + /// is not a valid format string. + public string ToString(string format) + { + return ToString(format, null); + } + + /// + /// Converts the numeric value of the current object to its equivalent string representation + /// by using the specified culture-specific formatting information. + /// + /// An object that supplies culture-specific formatting information. + /// + /// The string representation of the current value in the format specified by the + /// parameter. + /// + public string ToString(IFormatProvider provider) + { + return ToString(null, provider); + } + + /// + /// Converts the numeric value of the current object to its equivalent string representation + /// by using the specified format and culture-specific format information. + /// + /// A standard or custom numeric format string. + /// An object that supplies culture-specific formatting information. + /// + /// The string representation of the current value as specified by the + /// and parameters. + /// + public string ToString(string format, IFormatProvider provider) + { + if (string.IsNullOrEmpty(format)) + return ToString(10, provider); + + switch (format[0]) + { + case 'd': + case 'D': + case 'g': + case 'G': + case 'r': + case 'R': + return ToStringWithPadding(format, 10, provider); + case 'x': + case 'X': + return ToStringWithPadding(format, 16, null); + default: + throw new FormatException(string.Format("format '{0}' not implemented", format)); + } + } + + private static uint[] MakeTwoComplement(uint[] v) + { + var res = new uint[v.Length]; + + ulong carry = 1; + for (var i = 0; i < v.Length; ++i) + { + var word = v[i]; + carry = (ulong)~word + carry; + word = (uint)carry; + carry = (uint)(carry >> 32); + res[i] = word; + } + + var last = res[res.Length - 1]; + var idx = FirstNonFfByte(last); + uint mask = 0xFF; + for (var i = 1; i < idx; ++i) + mask = (mask << 8) | 0xFF; + + res[res.Length - 1] = last & mask; + return res; + } + + private string ToString(uint radix, IFormatProvider provider) + { + const string characterSet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + if (characterSet.Length < radix) + throw new ArgumentException("charSet length less than radix", "characterSet"); + if (radix == 1) + throw new ArgumentException("There is no such thing as radix one notation", "radix"); + if (_sign == 0) - return other == 0 ? 0 : -1; + return "0"; + if (_data.Length == 1 && _data[0] == 1) + return _sign == 1 ? "1" : "-1"; - if (_data.Length > 2) - return 1; + var digits = new List(1 + _data.Length * 3 / 10); - var high = (uint)(other >> 32); - var low = (uint)other; + BigInteger a; + if (_sign == 1) + a = this; + else + { + var dt = _data; + if (radix > 10) + dt = MakeTwoComplement(dt); + a = new BigInteger(1, dt); + } - return LongCompare(low, high); + while (a != 0) + { + BigInteger rem; + a = DivRem(a, radix, out rem); + digits.Add(characterSet[(int)rem]); + } + + if (_sign == -1 && radix == 10) + { + NumberFormatInfo info = null; + if (provider != null) + info = provider.GetFormat(typeof(NumberFormatInfo)) as NumberFormatInfo; + if (info != null) + { + var str = info.NegativeSign; + for (var i = str.Length - 1; i >= 0; --i) + digits.Add(str[i]); + } + else + { + digits.Add('-'); + } + } + + var last = digits[digits.Count - 1]; + if (_sign == 1 && radix > 10 && (last < '0' || last > '9')) + digits.Add('0'); + + digits.Reverse(); + + return new string(digits.ToArray()); } /// - /// Generates random BigInteger number + /// Converts the string representation of a number to its equivalent. /// - /// Length of random number in bits. - /// Big random number. - public static BigInteger Random(int bitLength) + /// A string that contains the number to convert. + /// + /// A value that is equivalent to the number specified in the parameter. + /// + /// is null. + /// is not in the correct format. + public static BigInteger Parse(string value) { - var bytesArray = new byte[bitLength / 8 + (((bitLength % 8) > 0) ? 1 : 0)]; - HashAlgorithmFactory.GenerateRandom(bytesArray); - bytesArray[bytesArray.Length - 1] = (byte)(bytesArray[bytesArray.Length - 1] & 0x7F); // Ensure not a negative value - return new BigInteger(bytesArray); + Exception ex; + BigInteger result; + + if (!Parse(value, false, out result, out ex)) + throw ex; + return result; } /// - /// Divides one System.Numerics.BigInteger value by another and returns the result. + /// Converts the string representation of a number in a specified style to its equivalent. + /// + /// A string that contains a number to convert. + /// A bitwise combination of the enumeration values that specify the permitted format of . + /// + /// A value that is equivalent to the number specified in the parameter. + /// + /// + /// is not a value. + /// -or- + /// includes the or flag along with another value. + /// + /// is null. + /// does not comply with the input pattern specified by . + public static BigInteger Parse(string value, NumberStyles style) + { + return Parse(value, style, null); + } + + /// + /// Converts the string representation of a number in a specified style to its equivalent. + /// + /// A string that contains a number to convert. + /// An object that provides culture-specific formatting information about . + /// + /// A value that is equivalent to the number specified in the parameter. + /// + /// is null. + /// is not in the correct format. + public static BigInteger Parse(string value, IFormatProvider provider) + { + return Parse(value, NumberStyles.Integer, provider); + } + + /// + /// Converts the string representation of a number in a specified style and culture-specific format to its equivalent. + /// + /// A string that contains a number to convert. + /// A bitwise combination of the enumeration values that specify the permitted format of . + /// An object that provides culture-specific formatting information about . + /// + /// A value that is equivalent to the number specified in the parameter. + /// + /// + /// is not a value. + /// -or- + /// includes the or flag along with another value. + /// + /// is null. + /// does not comply with the input pattern specified by . + public static BigInteger Parse(string value, NumberStyles style, IFormatProvider provider) + { + Exception exc; + BigInteger res; + + if (!Parse(value, style, provider, false, out res, out exc)) + throw exc; + + return res; + } + + /// + /// Tries to convert the string representation of a number to its equivalent, and + /// returns a value that indicates whether the conversion succeeded. + /// + /// The string representation of a number. + /// When this method returns, contains the equivalent to the number that is contained in value, or zero (0) if the conversion fails. The conversion fails if the parameter is null or is not of the correct format. This parameter is passed uninitialized. + /// + /// true if was converted successfully; otherwise, false. + /// + /// is null. + public static bool TryParse(string value, out BigInteger result) + { + Exception ex; + return Parse(value, true, out result, out ex); + } + + /// + /// Tries to convert the string representation of a number in a specified style and culture-specific format to its + /// equivalent, and returns a value that indicates whether the conversion succeeded. + /// + /// The string representation of a number. + /// A bitwise combination of enumeration values that indicates the style elements that can be present in . + /// An object that supplies culture-specific formatting information about . + /// When this method returns, contains the equivalent to the number that is contained in value, or if the conversion fails. The conversion fails if the parameter is null or is not of the correct format. This parameter is passed uninitialized. + /// + /// true if was converted successfully; otherwise, false. + /// + /// + /// is not a value. + /// -or- + /// includes the or flag along with another value. + /// + public static bool TryParse(string value, NumberStyles style, IFormatProvider provider, out BigInteger result) + { + Exception exc; + if (!Parse(value, style, provider, true, out result, out exc)) + { + result = Zero; + return false; + } + + return true; + } + + private static bool Parse(string value, NumberStyles style, IFormatProvider fp, bool tryParse, out BigInteger result, out Exception exc) + { + result = Zero; + exc = null; + + if (value == null) + { + if (!tryParse) + exc = new ArgumentNullException("value"); + return false; + } + + if (value.Length == 0) + { + if (!tryParse) + exc = GetFormatException(); + return false; + } + + NumberFormatInfo nfi = null; + if (fp != null) + { + var typeNfi = typeof(NumberFormatInfo); + nfi = (NumberFormatInfo) fp.GetFormat(typeNfi); + } + if (nfi == null) + nfi = Thread.CurrentThread.CurrentCulture.NumberFormat; + + if (!CheckStyle(style, tryParse, ref exc)) + return false; + + var allowCurrencySymbol = (style & NumberStyles.AllowCurrencySymbol) != 0; + var allowHexSpecifier = (style & NumberStyles.AllowHexSpecifier) != 0; + var allowThousands = (style & NumberStyles.AllowThousands) != 0; + var allowDecimalPoint = (style & NumberStyles.AllowDecimalPoint) != 0; + var allowParentheses = (style & NumberStyles.AllowParentheses) != 0; + var allowTrailingSign = (style & NumberStyles.AllowTrailingSign) != 0; + var allowLeadingSign = (style & NumberStyles.AllowLeadingSign) != 0; + var allowTrailingWhite = (style & NumberStyles.AllowTrailingWhite) != 0; + var allowLeadingWhite = (style & NumberStyles.AllowLeadingWhite) != 0; + var allowExponent = (style & NumberStyles.AllowExponent) != 0; + + var pos = 0; + + if (allowLeadingWhite && !JumpOverWhitespace(ref pos, value, true, tryParse, ref exc)) + return false; + + var foundOpenParentheses = false; + var negative = false; + var foundSign = false; + var foundCurrency = false; + + // Pre-number stuff + if (allowParentheses && value[pos] == '(') + { + foundOpenParentheses = true; + foundSign = true; + negative = true; // MS always make the number negative when there parentheses + // even when NumberFormatInfo.NumberNegativePattern != 0!!! + pos++; + if (allowLeadingWhite && !JumpOverWhitespace(ref pos, value, true, tryParse, ref exc)) + return false; + + if (value.Substring(pos, nfi.NegativeSign.Length) == nfi.NegativeSign) + { + if (!tryParse) + exc = GetFormatException(); + return false; + } + + if (value.Substring(pos, nfi.PositiveSign.Length) == nfi.PositiveSign) + { + if (!tryParse) + exc = GetFormatException(); + return false; + } + } + + if (allowLeadingSign && !foundSign) + { + // Sign + Currency + FindSign(ref pos, value, nfi, ref foundSign, ref negative); + if (foundSign) + { + if (allowLeadingWhite && !JumpOverWhitespace(ref pos, value, true, tryParse, ref exc)) + return false; + if (allowCurrencySymbol) + { + FindCurrency(ref pos, value, nfi, + ref foundCurrency); + if (foundCurrency && allowLeadingWhite && + !JumpOverWhitespace(ref pos, value, true, tryParse, ref exc)) + return false; + } + } + } + + if (allowCurrencySymbol && !foundCurrency) + { + // Currency + sign + FindCurrency(ref pos, value, nfi, ref foundCurrency); + if (foundCurrency) + { + if (allowLeadingWhite && !JumpOverWhitespace(ref pos, value, true, tryParse, ref exc)) + return false; + if (foundCurrency) + { + if (!foundSign && allowLeadingSign) + { + FindSign(ref pos, value, nfi, ref foundSign, + ref negative); + if (foundSign && allowLeadingWhite && + !JumpOverWhitespace(ref pos, value, true, tryParse, ref exc)) + return false; + } + } + } + } + + var number = Zero; + var nDigits = 0; + var decimalPointPos = -1; + var firstHexDigit = true; + + // Number stuff + while (pos < value.Length) + { + + if (!ValidDigit(value[pos], allowHexSpecifier)) + { + if (allowThousands && + (FindOther(ref pos, value, nfi.NumberGroupSeparator) + || FindOther(ref pos, value, nfi.CurrencyGroupSeparator))) + continue; + + if (allowDecimalPoint && decimalPointPos < 0 && + (FindOther(ref pos, value, nfi.NumberDecimalSeparator) + || FindOther(ref pos, value, nfi.CurrencyDecimalSeparator))) + { + decimalPointPos = nDigits; + continue; + } + + break; + } + + nDigits++; + + if (allowHexSpecifier) + { + var hexDigit = value[pos++]; + byte digitValue; + if (char.IsDigit(hexDigit)) + digitValue = (byte)(hexDigit - '0'); + else if (char.IsLower(hexDigit)) + digitValue = (byte)(hexDigit - 'a' + 10); + else + digitValue = (byte)(hexDigit - 'A' + 10); + + if (firstHexDigit && digitValue >= 8) + negative = true; + + number = number * 16 + digitValue; + firstHexDigit = false; + continue; + } + + number = number * 10 + (byte)(value[pos++] - '0'); + } + + // Post number stuff + if (nDigits == 0) + { + if (!tryParse) + exc = GetFormatException(); + return false; + } + + //Signed hex value (Two's Complement) + if (allowHexSpecifier && negative) + { + var mask = Pow(16, nDigits) - 1; + number = (number ^ mask) + 1; + } + + var exponent = 0; + if (allowExponent) + if (FindExponent(ref pos, value, ref exponent, tryParse, ref exc) && exc != null) + return false; + + if (allowTrailingSign && !foundSign) + { + // Sign + Currency + FindSign(ref pos, value, nfi, ref foundSign, ref negative); + if (foundSign && pos < value.Length) + { + if (allowTrailingWhite && !JumpOverWhitespace(ref pos, value, true, tryParse, ref exc)) + return false; + } + } + + if (allowCurrencySymbol && !foundCurrency) + { + if (allowTrailingWhite && pos < value.Length && !JumpOverWhitespace(ref pos, value, false, tryParse, ref exc)) + return false; + + // Currency + sign + FindCurrency(ref pos, value, nfi, ref foundCurrency); + if (foundCurrency && pos < value.Length) + { + if (allowTrailingWhite && !JumpOverWhitespace(ref pos, value, true, tryParse, ref exc)) + return false; + if (!foundSign && allowTrailingSign) + FindSign(ref pos, value, nfi, ref foundSign, + ref negative); + } + } + + if (allowTrailingWhite && pos < value.Length && !JumpOverWhitespace(ref pos, value, false, tryParse, ref exc)) + return false; + + if (foundOpenParentheses) + { + if (pos >= value.Length || value[pos++] != ')') + { + if (!tryParse) + exc = GetFormatException(); + return false; + } + if (allowTrailingWhite && pos < value.Length && !JumpOverWhitespace(ref pos, value, false, tryParse, ref exc)) + return false; + } + + if (pos < value.Length && value[pos] != '\u0000') + { + if (!tryParse) + exc = GetFormatException(); + return false; + } + + if (decimalPointPos >= 0) + exponent = exponent - nDigits + decimalPointPos; + + if (exponent < 0) + { + // + // Any non-zero values after decimal point are not allowed + // + BigInteger remainder; + number = DivRem(number, Pow(10, -exponent), out remainder); + + if (!remainder.IsZero) + { + if (!tryParse) + exc = new OverflowException("Value too large or too small. exp=" + exponent + " rem = " + remainder + " pow = " + Pow(10, -exponent)); + return false; + } + } + else if (exponent > 0) + { + number = Pow(10, exponent) * number; + } + + if (number._sign == 0) + result = number; + else if (negative) + result = new BigInteger(-1, number._data); + else + result = new BigInteger(1, number._data); + + return true; + } + + private static bool CheckStyle(NumberStyles style, bool tryParse, ref Exception exc) + { + if ((style & NumberStyles.AllowHexSpecifier) != 0) + { + var ne = style ^ NumberStyles.AllowHexSpecifier; + if ((ne & NumberStyles.AllowLeadingWhite) != 0) + ne ^= NumberStyles.AllowLeadingWhite; + if ((ne & NumberStyles.AllowTrailingWhite) != 0) + ne ^= NumberStyles.AllowTrailingWhite; + if (ne != 0) + { + if (!tryParse) + exc = new ArgumentException( + "With AllowHexSpecifier only " + + "AllowLeadingWhite and AllowTrailingWhite " + + "are permitted."); + return false; + } + } + else if ((uint)style > (uint)NumberStyles.Any) + { + if (!tryParse) + exc = new ArgumentException("Not a valid number style"); + return false; + } + + return true; + } + + private static bool JumpOverWhitespace(ref int pos, string s, bool reportError, bool tryParse, ref Exception exc) + { + while (pos < s.Length && char.IsWhiteSpace(s[pos])) + pos++; + + if (reportError && pos >= s.Length) + { + if (!tryParse) + exc = GetFormatException(); + return false; + } + + return true; + } + + private static void FindSign(ref int pos, string s, NumberFormatInfo nfi, ref bool foundSign, ref bool negative) + { + if ((pos + nfi.NegativeSign.Length) <= s.Length && + string.CompareOrdinal(s, pos, nfi.NegativeSign, 0, nfi.NegativeSign.Length) == 0) + { + negative = true; + foundSign = true; + pos += nfi.NegativeSign.Length; + } + else if ((pos + nfi.PositiveSign.Length) <= s.Length && + string.CompareOrdinal(s, pos, nfi.PositiveSign, 0, nfi.PositiveSign.Length) == 0) + { + negative = false; + pos += nfi.PositiveSign.Length; + foundSign = true; + } + } + + private static void FindCurrency(ref int pos, string s, NumberFormatInfo nfi, ref bool foundCurrency) + { + if ((pos + nfi.CurrencySymbol.Length) <= s.Length && + s.Substring(pos, nfi.CurrencySymbol.Length) == nfi.CurrencySymbol) + { + foundCurrency = true; + pos += nfi.CurrencySymbol.Length; + } + } + + private static bool FindExponent(ref int pos, string s, ref int exponent, bool tryParse, ref Exception exc) + { + exponent = 0; + + if (pos >= s.Length || (s[pos] != 'e' && s[pos] != 'E')) + { + exc = null; + return false; + } + + var i = pos + 1; + if (i == s.Length) + { + exc = tryParse ? null : GetFormatException(); + return true; + } + + var negative = false; + if (s[i] == '-') + { + negative = true; + if (++i == s.Length) + { + exc = tryParse ? null : GetFormatException(); + return true; + } + } + + if (s[i] == '+' && ++i == s.Length) + { + exc = tryParse ? null : GetFormatException(); + return true; + } + + long exp = 0; // temp long value + for (; i < s.Length; i++) + { + if (!char.IsDigit(s[i])) + { + exc = tryParse ? null : GetFormatException(); + return true; + } + + // Reduce the risk of throwing an overflow exc + exp = checked(exp * 10 - (int)(s[i] - '0')); + if (exp < int.MinValue || exp > int.MaxValue) + { + exc = tryParse ? null : new OverflowException("Value too large or too small."); + return true; + } + } + + // exp value saved as negative + if (!negative) + exp = -exp; + + exc = null; + exponent = (int) exp; + pos = i; + return true; + } + + private static bool FindOther(ref int pos, string s, string other) + { + if ((pos + other.Length) <= s.Length && + s.Substring(pos, other.Length) == other) + { + pos += other.Length; + return true; + } + + return false; + } + + private static bool ValidDigit(char e, bool allowHex) + { + if (allowHex) + return char.IsDigit(e) || (e >= 'A' && e <= 'F') || (e >= 'a' && e <= 'f'); + + return char.IsDigit(e); + } + + private static Exception GetFormatException() + { + return new FormatException("Input string was not in the correct format"); + } + + private static bool ProcessTrailingWhitespace(bool tryParse, string s, int position, ref Exception exc) + { + var len = s.Length; + + for (var i = position; i < len; i++) + { + var c = s[i]; + + if (c != 0 && !char.IsWhiteSpace(c)) + { + if (!tryParse) + exc = GetFormatException(); + return false; + } + } + return true; + } + + private static bool Parse(string value, bool tryParse, out BigInteger result, out Exception exc) + { + int i, sign = 1; + var digitsSeen = false; + + result = Zero; + exc = null; + + if (value == null) + { + if (!tryParse) + exc = new ArgumentNullException("value"); + return false; + } + + var len = value.Length; + + char c; + for (i = 0; i < len; i++) + { + c = value[i]; + if (!char.IsWhiteSpace(c)) + break; + } + + if (i == len) + { + if (!tryParse) + exc = GetFormatException(); + return false; + } + + var info = Thread.CurrentThread.CurrentCulture.NumberFormat; + + var negative = info.NegativeSign; + var positive = info.PositiveSign; + + if (string.CompareOrdinal(value, i, positive, 0, positive.Length) == 0) + i += positive.Length; + else if (string.CompareOrdinal(value, i, negative, 0, negative.Length) == 0) + { + sign = -1; + i += negative.Length; + } + + var val = Zero; + for (; i < len; i++) + { + c = value[i]; + + if (c == '\0') + { + i = len; + continue; + } + + if (c >= '0' && c <= '9') + { + var d = (byte)(c - '0'); + + val = val * 10 + d; + + digitsSeen = true; + } + else if (!ProcessTrailingWhitespace(tryParse, value, i, ref exc)) + return false; + } + + if (!digitsSeen) + { + if (!tryParse) + exc = GetFormatException(); + return false; + } + + if (val._sign == 0) + result = val; + else if (sign == -1) + result = new BigInteger(-1, val._data); + else + result = new BigInteger(1, val._data); + + return true; + } + + /// + /// Returns the smaller of two values. + /// + /// The first value to compare. + /// The second value to compare. + /// + /// The or parameter, whichever is smaller. + /// + public static BigInteger Min(BigInteger left, BigInteger right) + { + int ls = left._sign; + int rs = right._sign; + + if (ls < rs) + return left; + if (rs < ls) + return right; + + var r = CoreCompare(left._data, right._data); + if (ls == -1) + r = -r; + + if (r <= 0) + return left; + return right; + } + + /// + /// Returns the larger of two values. + /// + /// The first value to compare. + /// The second value to compare. + /// + /// The or parameter, whichever is larger. + /// + public static BigInteger Max(BigInteger left, BigInteger right) + { + int ls = left._sign; + int rs = right._sign; + + if (ls > rs) + return left; + if (rs > ls) + return right; + + var r = CoreCompare(left._data, right._data); + if (ls == -1) + r = -r; + + if (r >= 0) + return left; + return right; + } + + /// + /// Gets the absolute value of a object. + /// + /// A number. + /// + /// The absolute value of . + /// + public static BigInteger Abs(BigInteger value) + { + return new BigInteger((short)Math.Abs(value._sign), value._data); + } + + /// + /// Divides one value by another, returns the result, and returns the remainder in + /// an output parameter. /// /// The value to be divided. /// The value to divide by. - /// The quotient of the division. - public static BigInteger Divide(BigInteger dividend, BigInteger divisor) - { - return dividend / divisor; - } - - /// - /// Divides one System.Numerics.BigInteger value by another, returns the result, and returns the remainder in an output parameter. - /// - /// The value to be divided. - /// The value to divide by. - /// When this method returns, contains a System.Numerics.BigInteger value that - /// represents the remainder from the division. This parameter is passed uninitialized. - /// The quotient of the division. + /// When this method returns, contains a value that represents the remainder from the division. This parameter is passed uninitialized. + /// + /// The quotient of the division. + /// public static BigInteger DivRem(BigInteger dividend, BigInteger divisor, out BigInteger remainder) { if (divisor._sign == 0) @@ -2006,7 +3205,7 @@ namespace Renci.SshNet.Common for (i = remainderValue.Length - 1; i >= 0 && remainderValue[i] == 0; --i) ; if (i == -1) { - remainder = new BigInteger(0, _zero); + remainder = Zero; } else { @@ -2017,7 +3216,7 @@ namespace Renci.SshNet.Common for (i = quotient.Length - 1; i >= 0 && quotient[i] == 0; --i) ; if (i == -1) - return new BigInteger(0, _zero); + return Zero; if (i < quotient.Length - 1) quotient = Resize(quotient, i + 1); @@ -2025,94 +3224,89 @@ namespace Renci.SshNet.Common } /// - /// Returns a value that indicates whether the current instance and a specified System.Numerics.BigInteger object have the same value. + /// Raises a value to the power of a specified value. /// - /// The object to compare. + /// The number to raise to the power. + /// The exponent to raise by. /// - /// true if this System.Numerics.BigInteger object and other have the same value; otherwise, false. + /// The result of raising to the power. /// - public bool Equals(BigInteger other) + public static BigInteger Pow(BigInteger value, int exponent) { - if (_sign != other._sign) - return false; - if (_data.Length != other._data.Length) - return false; - for (var i = 0; i < _data.Length; ++i) + if (exponent < 0) + throw new ArgumentOutOfRangeException("exponent", "exp must be >= 0"); + if (exponent == 0) + return One; + if (exponent == 1) + return value; + + var result = One; + while (exponent != 0) { - if (_data[i] != other._data[i]) - return false; + if ((exponent & 1) != 0) + result = result * value; + if (exponent == 1) + break; + + value = value * value; + exponent >>= 1; } - return true; + return result; } /// - /// Returns a value that indicates whether the current instance and a signed 64-bit integer have the same value. + /// Performs modulus division on a number raised to the power of another number. /// - /// The signed 64-bit integer value to compare. - /// true if the signed 64-bit integer and the current instance have the same value; otherwise, false. - public bool Equals(long other) - { - return CompareTo(other) == 0; - } - - /// - /// Returns a value that indicates whether the current instance and a specified object have the same value. - /// - /// The object to compare. + /// The number to raise to the power. + /// The exponent to raise by. + /// The number by which to divide raised to the power. /// - /// true if the obj parameter is a System.Numerics.BigInteger object or a type - /// capable of implicit conversion to a System.Numerics.BigInteger value, and - /// its value is equal to the value of the current System.Numerics.BigInteger - /// object; otherwise, false. + /// The remainder after dividing raised by by + /// . /// - public override bool Equals(object obj) + /// is negative. + public static BigInteger ModPow(BigInteger value, BigInteger exponent, BigInteger modulus) { - if (!(obj is BigInteger)) - return false; - return Equals((BigInteger)obj); + if (exponent._sign == -1) + throw new ArgumentOutOfRangeException("exponent", "power must be >= 0"); + if (modulus._sign == 0) + throw new DivideByZeroException(); + + var result = One % modulus; + while (exponent._sign != 0) + { + if (!exponent.IsEven) + { + result = result * value; + result = result % modulus; + } + if (exponent.IsOne) + break; + value = value * value; + value = value % modulus; + exponent >>= 1; + } + return result; } /// - /// Returns a value that indicates whether the current instance and an unsigned 64-bit integer have the same value. - /// - /// The unsigned 64-bit integer to compare. - /// true if the current instance and the unsigned 64-bit integer have the same value; otherwise, false. - public bool Equals(ulong other) - { - return CompareTo(other) == 0; - } - - /// - /// Returns the hash code for the current System.Numerics.BigInteger object. - /// - /// - /// A 32-bit signed integer hash code. - /// - public override int GetHashCode() - { - var hash = (uint)(_sign * 0x01010101u); - - for (var i = 0; i < _data.Length; ++i) - hash ^= _data[i]; - return (int)hash; - } - - /// - /// Finds the greatest common divisor of two System.Numerics.BigInteger values. + /// Finds the greatest common divisor of two values. /// /// The first value. /// The second value. - /// The greatest common divisor of left and right. + /// + /// The greatest common divisor of and . + /// public static BigInteger GreatestCommonDivisor(BigInteger left, BigInteger right) { - if (left._data.Length == 1 && left._data[0] == 1) - return new BigInteger(1, _one); - if (right._data.Length == 1 && right._data[0] == 1) - return new BigInteger(1, _one); + if (left._sign != 0 && left._data.Length == 1 && left._data[0] == 1) + return One; + if (right._sign != 0 && right._data.Length == 1 && right._data[0] == 1) + return One; if (left.IsZero) - return right; + return Abs(right); if (right.IsZero) - return left; + return Abs(left); var x = new BigInteger(1, left._data); var y = new BigInteger(1, right._data); @@ -2157,25 +3351,29 @@ namespace Renci.SshNet.Common return yy << t; } + /*LAMESPEC Log doesn't specify to how many ulp is has to be precise + We are equilavent to MS with about 2 ULP + */ + /// /// Returns the logarithm of a specified number in a specified base. /// /// A number whose logarithm is to be found. /// The base of the logarithm. - /// The base baseValue logarithm of value, as shown in the table in the Remarks section. + /// + /// The base logarithm of value, + /// + /// The log of is out of range of the data type. public static double Log(BigInteger value, double baseValue) { - // LAMESPEC Log doesn't specify to how many ulp is has to be precise - // We are equilavent to MS with about 2 ULP - if (value._sign == -1 || baseValue == 1.0d || baseValue == -1.0d || - baseValue == double.NegativeInfinity || double.IsNaN(baseValue)) + baseValue == double.NegativeInfinity || double.IsNaN(baseValue)) return double.NaN; if (baseValue == 0.0d || baseValue == double.PositiveInfinity) return value.IsOne ? 0 : double.NaN; - if (value._sign == 0) + if (value._data == null) return double.NegativeInfinity; var length = value._data.Length - 1; @@ -2212,10 +3410,13 @@ namespace Renci.SshNet.Common } /// - /// Returns the natural (base e) logarithm of a specified number. + /// Returns the natural (base e) logarithm of a specified number. /// /// The number whose logarithm is to be found. - /// The natural (base e) logarithm of value, as shown in the table in the Remarks section. + /// + /// The natural (base e) logarithm of . + /// + /// The base 10 log of value is out of range of the data type. public static double Log(BigInteger value) { return Log(value, Math.E); @@ -2225,259 +3426,382 @@ namespace Renci.SshNet.Common /// Returns the base 10 logarithm of a specified number. /// /// A number whose logarithm is to be found. - /// The base 10 logarithm of value, as shown in the table in the Remarks section. + /// + /// The base 10 logarithm of . + /// + /// The base 10 log of value is out of range of the data type. public static double Log10(BigInteger value) { return Log(value, 10); } /// - /// Returns the larger of two System.Numerics.BigInteger values. + /// Returns a value that indicates whether the current instance and an unsigned 64-bit integer have the same value. /// - /// The first value to compare. - /// The second value to compare. - /// The left or right parameter, whichever is larger. - public static BigInteger Max(BigInteger left, BigInteger right) - { - int ls = left._sign; - int rs = right._sign; - - if (ls > rs) - return left; - if (rs > ls) - return right; - - var r = CoreCompare(left._data, right._data); - if (ls == -1) - r = -r; - - if (r >= 0) - return left; - return right; - } - - /// - /// Returns the smaller of two System.Numerics.BigInteger values. - /// - /// The first value to compare. - /// The second value to compare. - /// The left or right parameter, whichever is smaller. - public static BigInteger Min(BigInteger left, BigInteger right) - { - int ls = left._sign; - int rs = right._sign; - - if (ls < rs) - return left; - if (rs < ls) - return right; - - var r = CoreCompare(left._data, right._data); - if (ls == -1) - r = -r; - - if (r <= 0) - return left; - return right; - } - - /// - /// Performs modulus division on a number raised to the power of another number. - /// - /// The number to raise to the exponent power. - /// The exponent to raise value by. - /// The value to divide valueexponent by. - /// The remainder after dividing valueexponent by modulus. - public static BigInteger ModPow(BigInteger value, BigInteger exponent, BigInteger modulus) - { - if (exponent._sign == -1) - throw new ArgumentOutOfRangeException("exponent", "power must be >= 0"); - if (modulus._sign == 0) - throw new DivideByZeroException(); - - var result = One % modulus; - while (exponent._sign != 0) - { - if (!exponent.IsEven) - { - result = result * value; - result = result % modulus; - } - - if (exponent.IsOne) - break; - - value = value * value; - value = value % modulus; - exponent >>= 1; - } - return result; - } - - /// - /// Mods the inverse. - /// - /// The bi. - /// The modulus. - /// Modulus inverted number. - public static BigInteger ModInverse(BigInteger bi, BigInteger modulus) - { - BigInteger a = modulus, b = bi % modulus; - BigInteger p0 = 0, p1 = 1; - - while (!b.IsZero) - { - if (b.IsOne) - return p1; - - p0 += (a / b) * p1; - a %= b; - - if (a.IsZero) - break; - - if (a.IsOne) - return modulus - p0; - - p1 += (b / a) * p0; - b %= a; - - } - return 0; - } - - /// - /// Returns positive remainder that results from division with two specified values. - /// - /// The value to be divided. - /// The value to divide by. + /// The unsigned 64-bit integer to compare. /// - /// Positive remainder that results from the division. + /// true if the current instance and the unsigned 64-bit integer have the same value; otherwise, false. /// - public static BigInteger PositiveMod(BigInteger dividend, BigInteger divisor) + [CLSCompliant(false)] + public bool Equals(ulong other) { - var result = dividend % divisor; - if (result < 0) - result += divisor; - - return result; + return CompareTo(other) == 0; } /// - /// Returns the product of two System.Numerics.BigInteger values. + /// Returns the hash code for the current object. /// - /// The first number to multiply. - /// The second number to multiply. - /// The product of the left and right parameters. - public static BigInteger Multiply(BigInteger left, BigInteger right) + /// + /// A 32-bit signed integer hash code. + /// + public override int GetHashCode() { - return left * right; - } - - /// - /// Negates a specified System.Numerics.BigInteger value. - /// - /// The value to negate. - /// The result of the value parameter multiplied by negative one (-1). - public static BigInteger Negate(BigInteger value) - { - return -value; - } - - /// - /// Converts the string representation of a number in a specified style and culture-specific format to its equivalent. - /// - /// A string that contains a number to convert. - /// A bitwise combination of the enumeration values that specify the permitted format of value. - /// An object that provides culture-specific formatting information about value. - /// Parsed number - public static BigInteger Parse(string value, NumberStyles style, IFormatProvider provider) - { - Exception ex; - BigInteger result; - - if (!Parse(value, false, style, provider, out result, out ex)) - throw ex; - return result; - } - - /// - /// Converts the string representation of a number in a specified culture-specific format to its System.Numerics.BigInteger equivalent. - /// - /// A string that contains a number to convert. - /// An object that provides culture-specific formatting information about value. - /// A value that is equivalent to the number specified in the value parameter. - public static BigInteger Parse(string value, IFormatProvider provider) - { - throw new NotImplementedException(); - } - - /// - /// Converts the string representation of a number in a specified style to its System.Numerics.BigInteger equivalent. - /// - /// A string that contains a number to convert. - /// A bitwise combination of the enumeration values that specify the permitted format of value. - /// A value that is equivalent to the number specified in the value parameter. - public static BigInteger Parse(string value, NumberStyles style) - { - throw new NotImplementedException(); - } - - /// - /// Raises a System.Numerics.BigInteger value to the power of a specified value. - /// - /// The number to raise to the exponent power. - /// The exponent to raise value by. - /// The result of raising value to the exponent power. - public static BigInteger Pow(BigInteger value, int exponent) - { - if (exponent < 0) - throw new ArgumentOutOfRangeException("exponent", "exp must be >= 0"); - if (exponent == 0) - return One; - if (exponent == 1) - return value; - - var result = One; - while (exponent != 0) + var hash = (uint)(_sign * 0x01010101u); + if (_data != null) { - if ((exponent & 1) != 0) - result = result * value; - if (exponent == 1) - break; - - value = value * value; - exponent >>= 1; + foreach (var bit in _data) + hash ^= bit; } - return result; + + return (int)hash; } /// - /// Performs integer division on two System.Numerics.BigInteger values and returns the remainder. + /// Adds two values and returns the result. /// - /// The value to be divided. - /// The value to divide by. - /// The remainder after dividing dividend by divisor. - public static BigInteger Remainder(BigInteger dividend, BigInteger divisor) + /// The first value to add. + /// The second value to add. + /// + /// The sum of and . + /// + public static BigInteger Add(BigInteger left, BigInteger right) { - return dividend % divisor; + return left + right; } /// - /// Subtracts one System.Numerics.BigInteger value from another and returns the result. + /// Subtracts one value from another and returns the result. /// /// The value to subtract from (the minuend). /// The value to subtract (the subtrahend). - /// The result of subtracting right from left. + /// + /// The result of subtracting from . + /// public static BigInteger Subtract(BigInteger left, BigInteger right) { return left - right; } /// - /// Converts a System.Numerics.BigInteger value to a byte array. + /// Returns the product of two values. /// - /// The value of the current System.Numerics.BigInteger object converted to an array of bytes. + /// The first number to multiply. + /// The second number to multiply. + /// + /// The product of the and parameters. + /// + public static BigInteger Multiply(BigInteger left, BigInteger right) + { + return left * right; + } + + /// + /// Divides one value by another and returns the result. + /// + /// The value to be divided. + /// The value to divide by. + /// + /// The quotient of the division. + /// + public static BigInteger Divide(BigInteger dividend, BigInteger divisor) + { + return dividend / divisor; + } + + /// + /// Performs integer division on two values and returns the remainder. + /// + /// The value to be divided. + /// The value to divide by. + /// + /// The remainder after dividing by . + /// + public static BigInteger Remainder(BigInteger dividend, BigInteger divisor) + { + return dividend % divisor; + } + + /// + /// Negates a specified value. + /// + /// The value to negate. + /// + /// The result of the parameter multiplied by negative one (-1). + /// + public static BigInteger Negate(BigInteger value) + { + return -value; + } + + /// + /// Compares this instance to a specified object and returns an integer that indicates whether the value of + /// this instance is less than, equal to, or greater than the value of the specified object. + /// + /// The object to compare. + /// + /// A signed integer that indicates the relationship of the current instance to the parameter, + /// as shown in the following table. + /// + /// + /// Value + /// Condition + /// + /// + /// Less than zero + /// The current instance is less than . + /// + /// + /// Zero + /// The current instance equals . + /// + /// + /// Greater than zero + /// The current instance is greater than . + /// + /// + /// + /// is not a . + public int CompareTo(object obj) + { + if (obj == null) + return 1; + + if (!(obj is BigInteger)) + return -1; + + return Compare(this, (BigInteger)obj); + } + + /// + /// Compares this instance to a second and returns an integer that indicates whether the + /// value of this instance is less than, equal to, or greater than the value of the specified object. + /// + /// The object to compare. + /// + /// A signed integer value that indicates the relationship of this instance to , as + /// shown in the following table. + /// + /// + /// Value + /// Condition + /// + /// + /// Less than zero + /// The current instance is less than . + /// + /// + /// Zero + /// The current instance equals . + /// + /// + /// Greater than zero + /// The current instance is greater than . + /// + /// + /// + public int CompareTo(BigInteger other) + { + return Compare(this, other); + } + + /// + /// Compares this instance to an unsigned 64-bit integer and returns an integer that indicates whether the value of this + /// instance is less than, equal to, or greater than the value of the unsigned 64-bit integer. + /// + /// The unsigned 64-bit integer to compare. + /// + /// A signed integer that indicates the relative value of this instance and , as shown + /// in the following table. + /// + /// + /// Value + /// Condition + /// + /// + /// Less than zero + /// The current instance is less than . + /// + /// + /// Zero + /// The current instance equals . + /// + /// + /// Greater than zero + /// The current instance is greater than . + /// + /// + /// + [CLSCompliant(false)] + public int CompareTo(ulong other) + { + if (_sign < 0) + return -1; + if (_sign == 0) + return other == 0 ? 0 : -1; + + if (_data.Length > 2) + return 1; + + var high = (uint)(other >> 32); + var low = (uint)other; + + return LongCompare(low, high); + } + + private int LongCompare(uint low, uint high) + { + uint h = 0; + if (_data.Length > 1) + h = _data[1]; + + if (h > high) + return 1; + if (h < high) + return -1; + + var l = _data[0]; + + if (l > low) + return 1; + if (l < low) + return -1; + + return 0; + } + + /// + /// Compares this instance to a signed 64-bit integer and returns an integer that indicates whether the value of this + /// instance is less than, equal to, or greater than the value of the signed 64-bit integer. + /// + /// The signed 64-bit integer to compare. + /// + /// A signed integer that indicates the relative value of this instance and , as shown + /// in the following table. + /// + /// + /// Value + /// Condition + /// + /// + /// Less than zero + /// The current instance is less than . + /// + /// + /// Zero + /// The current instance equals . + /// + /// + /// Greater than zero + /// The current instance is greater than . + /// + /// + /// + public int CompareTo(long other) + { + int ls = _sign; + var rs = Math.Sign(other); + + if (ls != rs) + return ls > rs ? 1 : -1; + + if (ls == 0) + return 0; + + if (_data.Length > 2) + return _sign; + + if (other < 0) + other = -other; + var low = (uint)other; + var high = (uint)((ulong)other >> 32); + + var r = LongCompare(low, high); + if (ls == -1) + r = -r; + + return r; + } + + /// + /// Compares two values and returns an integer that indicates whether the first value is less than, equal to, or greater than the second value. + /// + /// The first value to compare. + /// The second value to compare. + /// + /// A signed integer that indicates the relative values of left and right, as shown in the following table. + /// + /// + /// Value + /// Condition + /// + /// + /// Less than zero + /// is less than . + /// + /// + /// Zero + /// equals . + /// + /// + /// Greater than zero + /// is greater than . + /// + /// + /// + public static int Compare(BigInteger left, BigInteger right) + { + int ls = left._sign; + int rs = right._sign; + + if (ls != rs) + return ls > rs ? 1 : -1; + + var r = CoreCompare(left._data, right._data); + if (ls < 0) + r = -r; + return r; + } + + private static int TopByte(uint x) + { + if ((x & 0xFFFF0000u) != 0) + { + if ((x & 0xFF000000u) != 0) + return 4; + return 3; + } + if ((x & 0xFF00u) != 0) + return 2; + return 1; + } + + private static int FirstNonFfByte(uint word) + { + if ((word & 0xFF000000u) != 0xFF000000u) + return 4; + if ((word & 0xFF0000u) != 0xFF0000u) + return 3; + if ((word & 0xFF00u) != 0xFF00u) + return 2; + return 1; + } + + /// + /// Converts a value to a byte array. + /// + /// + /// The value of the current object converted to an array of bytes. + /// public byte[] ToByteArray() { if (_sign == 0) @@ -2490,7 +3814,7 @@ namespace Renci.SshNet.Common var topWord = _data[_data.Length - 1]; int extra; - //if the topmost bit is set we need an extra + //if the topmost bit is set we need an extra if (_sign == 1) { extra = TopByte(topWord); @@ -2550,8 +3874,8 @@ namespace Renci.SshNet.Common carry = (uint)(add >> 32); if (carry == 0) { - int ex = FirstNonFFByte(word); - bool needExtra = (word & (1 << (ex * 8 - 1))) == 0; + var ex = FirstNonFfByte(word); + var needExtra = (word & (1 << (ex * 8 - 1))) == 0; var to = ex + (needExtra ? 1 : 0); if (to != extra) @@ -2579,540 +3903,9 @@ namespace Renci.SshNet.Common return res; } - /// - /// Converts the numeric value of the current System.Numerics.BigInteger object to its equivalent string representation. - /// - /// - /// The string representation of the current System.Numerics.BigInteger value. - /// - public override string ToString() - { - return ToString(10, null); - } - - /// - /// Converts the numeric value of the current System.Numerics.BigInteger object - /// to its equivalent string representation by using the specified culture-specific - /// formatting information. - /// - /// An object that supplies culture-specific formatting information. - /// - /// The string representation of the current System.Numerics.BigInteger value - /// in the format specified by the provider parameter. - /// - public string ToString(IFormatProvider provider) - { - return ToString(null, provider); - } - - /// - /// Converts the numeric value of the current System.Numerics.BigInteger object - /// to its equivalent string representation by using the specified format. - /// - /// A standard or custom numeric format string. - /// - /// The string representation of the current System.Numerics.BigInteger value - /// in the format specified by the format parameter. - /// - public string ToString(string format) - { - return ToString(format, null); - } - - /// - /// Converts the numeric value of the current System.Numerics.BigInteger object - /// to its equivalent string representation by using the specified format and - /// culture-specific format information. - /// - /// A standard or custom numeric format string. - /// An object that supplies culture-specific formatting information. - /// - /// The string representation of the current System.Numerics.BigInteger value - /// as specified by the format and provider parameters. - /// - public string ToString(string format, IFormatProvider provider) - { - if (string.IsNullOrEmpty(format)) - return ToString(10, provider); - - switch (format[0]) - { - case 'd': - case 'D': - case 'g': - case 'G': - case 'r': - case 'R': - return ToStringWithPadding(format, 10, provider); - case 'x': - case 'X': - return ToStringWithPadding(format, 16, null); - default: - throw new FormatException(string.Format("format '{0}' not implemented", format)); - } - } - - /// - /// Tries to convert the string representation of a number in a specified style - /// and culture-specific format to its System.Numerics.BigInteger equivalent, - /// and returns a value that indicates whether the conversion succeeded. - /// - /// The string representation of a number. The string is interpreted using the style specified by style. - /// A bitwise combination of enumeration values that indicates the style elements - /// that can be present in value. A typical value to specify is System.Globalization.NumberStyles.Integer. - /// An object that supplies culture-specific formatting information about value. - /// When this method returns, contains the System.Numerics.BigInteger equivalent - /// to the number that is contained in value, or System.Numerics.BigInteger.Zero - /// if the conversion failed. The conversion fails if the value parameter is - /// null or is not in a format that is compliant with style. This parameter is - /// passed uninitialized. - /// true if the value parameter was converted successfully; otherwise, false. - public static bool TryParse(string value, NumberStyles style, CultureInfo cultureInfo, out BigInteger result) - { - Exception ex; - return Parse(value, true, style, cultureInfo, out result, out ex); - } - - /// - /// Tries to convert the string representation of a number to its System.Numerics.BigInteger - /// equivalent, and returns a value that indicates whether the conversion succeeded. - /// - /// The string representation of a number. - /// When this method returns, contains the System.Numerics.BigInteger equivalent - /// to the number that is contained in value, or zero (0) if the conversion fails. - /// The conversion fails if the value parameter is null or is not of the correct - /// format. This parameter is passed uninitialized. - /// true if value was converted successfully; otherwise, false. - public static bool TryParse(string value, out BigInteger result) - { - throw new NotImplementedException(); - } - - /// - /// Compares this instance to a signed 64-bit integer and returns an integer - /// that indicates whether the value of this instance is less than, equal to, - /// or greater than the value of the signed 64-bit integer. - /// - /// The signed 64-bit integer to compare. - /// A signed integer value that indicates the relationship of this instance to - /// other, as shown in the following table.Return valueDescriptionLess than zeroThe - /// current instance is less than other.ZeroThe current instance equals other.Greater - /// than zero.The current instance is greater than other. - public int CompareTo(long other) - { - var ls = _sign; - var rs = Math.Sign(other); - - if (ls != rs) - return ls > rs ? 1 : -1; - - if (ls == 0) - return 0; - - if (_data.Length > 2) - return _sign; - - if (other < 0) - other = -other; - var low = (uint)other; - var high = (uint)((ulong)other >> 32); - - var r = LongCompare(low, high); - if (ls == -1) - r = -r; - - return r; - } - - /// - /// Compares two System.Numerics.BigInteger values and returns an integer that - /// indicates whether the first value is less than, equal to, or greater than the second value. - /// - /// The first value to compare. - /// The second value to compare. - /// A signed integer that indicates the relative values of left and right, - /// as shown in the following table.ValueConditionLess than zeroleft is less than right.Zeroleft - /// equals right.Greater than zeroleft is greater than right. - public static int Compare(BigInteger left, BigInteger right) - { - var ls = left._sign; - var rs = right._sign; - - if (ls != rs) - return ls > rs ? 1 : -1; - - var r = CoreCompare(left._data, right._data); - if (ls < 0) - r = -r; - return r; - } - - private static bool Negative(byte[] v) - { - return ((v[7] & 0x80) != 0); - } - - private static ushort Exponent(byte[] v) - { - return (ushort)((((ushort)(v[7] & 0x7F)) << (ushort)4) | (((ushort)(v[6] & 0xF0)) >> 4)); - } - - private static ulong Mantissa(byte[] v) - { - var i1 = ((uint)v[0] | ((uint)v[1] << 8) | ((uint)v[2] << 16) | ((uint)v[3] << 24)); - var i2 = ((uint)v[4] | ((uint)v[5] << 8) | ((uint)(v[6] & 0xF) << 16)); - - return (ulong)i1 | ((ulong)i2 << 32); - } - - /// - /// Populations the count. - /// - /// The x. - /// Returns the number of bits set in x - private static int PopulationCount(uint x) - { - x = x - ((x >> 1) & 0x55555555); - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); - x = (x + (x >> 4)) & 0x0F0F0F0F; - x = x + (x >> 8); - x = x + (x >> 16); - return (int)(x & 0x0000003F); - } - - private string ToStringWithPadding(string format, uint radix, IFormatProvider provider) - { - if (format.Length > 1) - { - var precision = Convert.ToInt32(format.Substring(1), CultureInfo.InvariantCulture.NumberFormat); - var baseStr = ToString(radix, provider); - if (baseStr.Length < precision) - { - var additional = new string('0', precision - baseStr.Length); - if (baseStr[0] != '-') - { - return additional + baseStr; - } - return "-" + additional + baseStr.Substring(1); - } - return baseStr; - } - return ToString(radix, provider); - } - - private static uint[] MakeTwoComplement(uint[] v) - { - var res = new uint[v.Length]; - - ulong carry = 1; - for (var i = 0; i < v.Length; ++i) - { - var word = v[i]; - carry = (ulong)~word + carry; - word = (uint)carry; - carry = (uint)(carry >> 32); - res[i] = word; - } - - var last = res[res.Length - 1]; - var idx = FirstNonFFByte(last); - uint mask = 0xFF; - for (var i = 1; i < idx; ++i) - mask = (mask << 8) | 0xFF; - - res[res.Length - 1] = last & mask; - return res; - } - - private string ToString(uint radix, IFormatProvider provider) - { - const string characterSet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - if (characterSet.Length < radix) - throw new ArgumentException("charSet length less than radix", "characterSet"); - if (radix == 1) - throw new ArgumentException("There is no such thing as radix one notation", "radix"); - - if (_sign == 0) - return "0"; - if (_data.Length == 1 && _data[0] == 1) - return _sign == 1 ? "1" : "-1"; - - var digits = new List(1 + _data.Length * 3 / 10); - - BigInteger a; - if (_sign == 1) - a = this; - else - { - uint[] dt = _data; - if (radix > 10) - dt = MakeTwoComplement(dt); - a = new BigInteger(1, dt); - } - - while (a != 0) - { - BigInteger rem; - a = DivRem(a, radix, out rem); - digits.Add(characterSet[(int)rem]); - } - - if (_sign == -1 && radix == 10) - { - NumberFormatInfo info = null; - if (provider != null) - info = provider.GetFormat(typeof(NumberFormatInfo)) as NumberFormatInfo; - if (info != null) - { - var str = info.NegativeSign; - for (var i = str.Length - 1; i >= 0; --i) - digits.Add(str[i]); - } - else - { - digits.Add('-'); - } - } - - var last = digits[digits.Count - 1]; - if (_sign == 1 && radix > 10 && (last < '0' || last > '9')) - digits.Add('0'); - - digits.Reverse(); - - return new string(digits.ToArray()); - } - - private static Exception GetFormatException() - { - return new FormatException("Input string was not in the correct format"); - } - - private static bool ProcessTrailingWhitespace(bool tryParse, string s, int position, ref Exception exc) - { - var len = s.Length; - - for (var i = position; i < len; i++) - { - var c = s[i]; - - if (c != 0 && !char.IsWhiteSpace(c)) - { - if (!tryParse) - exc = GetFormatException(); - return false; - } - } - return true; - } - - private static bool Parse(string s, bool tryParse, NumberStyles style, IFormatProvider provider, out BigInteger result, out Exception exc) - { - int i, sign = 1; - var digitsSeen = false; - - var baseNumber = 10; - switch (style) - { - case NumberStyles.None: - break; - case NumberStyles.HexNumber: - case NumberStyles.AllowHexSpecifier: - baseNumber = 16; - break; - case NumberStyles.AllowCurrencySymbol: - case NumberStyles.AllowDecimalPoint: - case NumberStyles.AllowExponent: - case NumberStyles.AllowLeadingSign: - case NumberStyles.AllowLeadingWhite: - case NumberStyles.AllowParentheses: - case NumberStyles.AllowThousands: - case NumberStyles.AllowTrailingSign: - case NumberStyles.AllowTrailingWhite: - case NumberStyles.Any: - case NumberStyles.Currency: - case NumberStyles.Float: - case NumberStyles.Integer: - case NumberStyles.Number: - default: - throw new NotSupportedException(string.Format("Style '{0}' is not supported.", style)); - } - - result = Zero; - exc = null; - - if (s == null) - { - if (!tryParse) - exc = new ArgumentNullException("value"); - return false; - } - - var len = s.Length; - - char c; - for (i = 0; i < len; i++) - { - c = s[i]; - if (!char.IsWhiteSpace(c)) - break; - } - - if (i == len) - { - if (!tryParse) - exc = GetFormatException(); - return false; - } - - var info = (NumberFormatInfo) provider.GetFormat(typeof (NumberFormatInfo)); - - var negative = info.NegativeSign; - var positive = info.PositiveSign; - - if (string.CompareOrdinal(s, i, positive, 0, positive.Length) == 0) - i += positive.Length; - else if (string.CompareOrdinal(s, i, negative, 0, negative.Length) == 0) - { - sign = -1; - i += negative.Length; - } - - var val = Zero; - for (; i < len; i++) - { - c = s[i]; - - if (c == '\0') - { - i = len; - continue; - } - - if (c >= '0' && c <= '9') - { - var d = (byte)(c - '0'); - - val = val * baseNumber + d; - - digitsSeen = true; - } - else if (c >= 'A' && c <= 'F') - { - var d = (byte)(c - 'A' + 10); - - val = val * baseNumber + d; - - digitsSeen = true; - } - else if (!ProcessTrailingWhitespace(tryParse, s, i, ref exc)) - return false; - } - - if (!digitsSeen) - { - if (!tryParse) - exc = GetFormatException(); - return false; - } - - if (val._sign == 0) - result = val; - else if (sign == -1) - result = new BigInteger(-1, val._data); - else - result = new BigInteger(1, val._data); - - return true; - } - - private int LongCompare(uint low, uint high) - { - uint h = 0; - if (_data.Length > 1) - h = _data[1]; - - if (h > high) - return 1; - if (h < high) - return -1; - - var l = _data[0]; - - if (l > low) - return 1; - if (l < low) - return -1; - - return 0; - } - - private bool AsInt32(out int val) - { - val = 0; - if (_data.Length > 1) return false; - var d = _data[0]; - - if (_sign == 1) - { - if (d > (uint)int.MaxValue) - return false; - val = (int)d; - } - else if (_sign == -1) - { - if (d > 0x80000000u) - return false; - val = -(int)d; - } - return true; - } - - /// - /// Returns the 0-based index of the most significant set bit - /// - /// The word. - /// 0 if no bit is set - private static int BitScanBackward(uint word) - { - for (var i = 31; i >= 0; --i) - { - var mask = 1u << i; - if ((word & mask) == mask) - return i; - } - return 0; - } - - private static int TopByte(uint x) - { - if ((x & 0xFFFF0000u) != 0) - { - if ((x & 0xFF000000u) != 0) - return 4; - return 3; - } - if ((x & 0xFF00u) != 0) - return 2; - return 1; - } - - private static int FirstNonFFByte(uint word) - { - if ((word & 0xFF000000u) != 0xFF000000u) - return 4; - if ((word & 0xFF0000u) != 0xFF0000u) - return 3; - if ((word & 0xFF00u) != 0xFF00u) - return 2; - return 1; - } - private static byte[] Resize(byte[] v, int len) { var res = new byte[len]; - Buffer.BlockCopy(v, 0, res, 0, Math.Min(v.Length, len)); Array.Copy(v, res, Math.Min(v.Length, len)); return res; } @@ -3120,7 +3913,7 @@ namespace Renci.SshNet.Common private static uint[] Resize(uint[] v, int len) { var res = new uint[len]; - Buffer.BlockCopy(v, 0, res, 0, Math.Min(v.Length, len) * sizeof(uint)); + Array.Copy(v, res, Math.Min(v.Length, len)); return res; } @@ -3244,8 +4037,8 @@ namespace Renci.SshNet.Common private static int CoreCompare(uint[] a, uint[] b) { - var al = a.Length; - var bl = b.Length; + var al = a != null ? a.Length : 0; + var bl = b != null ? b.Length : 0; if (al > bl) return 1; @@ -3342,7 +4135,7 @@ namespace Renci.SshNet.Common if (n <= 1) { - // Divide by single digit + // Divide by single digit // ulong rem = 0; var v0 = v[0]; @@ -3373,7 +4166,7 @@ namespace Renci.SshNet.Common q = new uint[m - n + 1]; r = null; - // Main division loop + // Main division loop // for (var j = m - n; j >= 0; j--) { @@ -3383,7 +4176,7 @@ namespace Renci.SshNet.Common var qq = rr / vn[n - 1]; rr -= qq * vn[n - 1]; - for (; ; ) + for (;;) { // Estimate too big ? // @@ -3398,13 +4191,13 @@ namespace Renci.SshNet.Common } - // Multiply and subtract + // Multiply and subtract // long b = 0; - long t; + long t = 0; for (i = 0; i < n; i++) { - ulong p = vn[i] * qq; + var p = vn[i] * qq; t = (long)un[i + j] - (long)(uint)p - b; un[i + j] = (uint)t; p >>= 32; @@ -3414,11 +4207,11 @@ namespace Renci.SshNet.Common t = (long)un[j + n] - b; un[j + n] = (uint)t; - // Store the calculated value + // Store the calculated value // q[j] = (uint)qq; - // Add back vn[0..n] to un[j..j+n] + // Add back vn[0..n] to un[j..j+n] // if (t < 0) { @@ -3444,4 +4237,4 @@ namespace Renci.SshNet.Common } } } -} \ No newline at end of file +}