From 61fc7a042054dd0c28a7618a6381f730aa7a87ee Mon Sep 17 00:00:00 2001 From: Maksim Golev Date: Tue, 13 Jul 2021 16:18:44 +0400 Subject: [PATCH 01/10] Switching to TheoryAttribute for testing Explicit converting of BigInteger. (#49611) --- .../tests/BigInteger/cast_from.cs | 1094 ++++++----------- 1 file changed, 349 insertions(+), 745 deletions(-) diff --git a/src/libraries/System.Runtime.Numerics/tests/BigInteger/cast_from.cs b/src/libraries/System.Runtime.Numerics/tests/BigInteger/cast_from.cs index d6343326642bd..6c30b1606a8ee 100644 --- a/src/libraries/System.Runtime.Numerics/tests/BigInteger/cast_from.cs +++ b/src/libraries/System.Runtime.Numerics/tests/BigInteger/cast_from.cs @@ -1,732 +1,490 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; +using System.Collections.Generic; using Xunit; namespace System.Numerics.Tests { public class cast_fromTest { - public delegate void ExceptionGenerator(); - private const int NumberOfRandomIterations = 10; private static Random s_random = new Random(100); - [Fact] - public static void RunByteExplicitCastFromBigIntegerTests() + public static IEnumerable RunByteExplicitCastFromBigIntegerTestSources { - byte value = 0; - BigInteger bigInteger; - - // Byte Explicit Cast from BigInteger: Random value < Byte.MinValue - bigInteger = GenerateRandomBigIntegerLessThan(byte.MinValue, s_random); - value = bigInteger.ToByteArray()[0]; - Assert.Throws(() => VerifyByteExplicitCastFromBigInteger(value, bigInteger)); - - // Byte Explicit Cast from BigInteger: Byte.MinValue - 1 - bigInteger = new BigInteger(byte.MinValue); - bigInteger -= BigInteger.One; - value = bigInteger.ToByteArray()[0]; - Assert.Throws(() => VerifyByteExplicitCastFromBigInteger(value, bigInteger)); - - // Byte Explicit Cast from BigInteger: Byte.MinValue - VerifyByteExplicitCastFromBigInteger(byte.MinValue); - - // Byte Explicit Cast from BigInteger: 0 - VerifyByteExplicitCastFromBigInteger(0); - - // Byte Explicit Cast from BigInteger: 1 - VerifyByteExplicitCastFromBigInteger(1); - - // Byte Explicit Cast from BigInteger: Random Positive - for (int i = 0; i < NumberOfRandomIterations; ++i) + get { - VerifyByteExplicitCastFromBigInteger((byte)s_random.Next(1, byte.MaxValue)); + yield return new object[] { new BigInteger(byte.MinValue), byte.MinValue }; + yield return new object[] { new BigInteger(byte.MaxValue), byte.MaxValue }; + yield return new object[] { new BigInteger(0), 0 }; + yield return new object[] { new BigInteger(1), 1 }; + for (int i = 0; i < NumberOfRandomIterations; i++) + { + byte currentValue = (byte)s_random.Next(byte.MinValue, byte.MaxValue); + yield return new object[] { new BigInteger(currentValue), currentValue }; + } } - - // Byte Explicit Cast from BigInteger: Byte.MaxValue + 1 - bigInteger = new BigInteger(byte.MaxValue); - bigInteger += BigInteger.One; - value = bigInteger.ToByteArray()[0]; - Assert.Throws(() => VerifyByteExplicitCastFromBigInteger(value, bigInteger)); - - // Byte Explicit Cast from BigInteger: Random value > Byte.MaxValue - bigInteger = GenerateRandomBigIntegerGreaterThan(byte.MaxValue, s_random); - value = bigInteger.ToByteArray()[0]; - Assert.Throws(() => VerifyByteExplicitCastFromBigInteger(value, bigInteger)); } - [Fact] - public static void RunSByteExplicitCastFromBigIntegerTests() + [Theory] + [MemberData(nameof(RunByteExplicitCastFromBigIntegerTestSources))] + public void RunByteExplicitCastFromBigIntegerTest(BigInteger testValue, byte expectedValue) { - sbyte value = 0; - BigInteger bigInteger; + byte actualValue; - // SByte Explicit Cast from BigInteger: Random value < SByte.MinValue - bigInteger = GenerateRandomBigIntegerLessThan(sbyte.MinValue, s_random); - value = unchecked((sbyte)bigInteger.ToByteArray()[0]); - Assert.Throws(() => VerifySByteExplicitCastFromBigInteger(value, bigInteger)); + actualValue = (byte)testValue; - // SByte Explicit Cast from BigInteger: SByte.MinValue - 1 - bigInteger = new BigInteger(sbyte.MinValue); - bigInteger -= BigInteger.One; - value = (sbyte)bigInteger.ToByteArray()[0]; - Assert.Throws(() => VerifySByteExplicitCastFromBigInteger(value, bigInteger)); - - // SByte Explicit Cast from BigInteger: SByte.MinValue - VerifySByteExplicitCastFromBigInteger(sbyte.MinValue); + Assert.Equal(expectedValue, actualValue); + } - // SByte Explicit Cast from BigInteger: Random Negative - for (int i = 0; i < NumberOfRandomIterations; ++i) + public static IEnumerable RunByteExplicitCastFromBigIntegerThrowsOverflowExceptionTestSources + { + get { - VerifySByteExplicitCastFromBigInteger((sbyte)s_random.Next(sbyte.MinValue, 0)); + yield return new object[] { byte.MinValue - BigInteger.One }; + yield return new object[] { byte.MaxValue + BigInteger.One }; + yield return new object[] { GenerateRandomBigIntegerLessThan(byte.MinValue, s_random) }; + yield return new object[] { GenerateRandomBigIntegerGreaterThan(byte.MaxValue, s_random) }; } + } - // SByte Explicit Cast from BigInteger: -1 - VerifySByteExplicitCastFromBigInteger(-1); - - // SByte Explicit Cast from BigInteger: 0 - VerifySByteExplicitCastFromBigInteger(0); - - // SByte Explicit Cast from BigInteger: 1 - VerifySByteExplicitCastFromBigInteger(1); + [Theory] + [MemberData(nameof(RunByteExplicitCastFromBigIntegerThrowsOverflowExceptionTestSources))] + public void RunByteExplicitCastFromBigIntegerThrowsOverflowExceptionTest(BigInteger testValue) + { + Assert.Throws(() => (byte)testValue); + } - // SByte Explicit Cast from BigInteger: Random Positive - for (int i = 0; i < NumberOfRandomIterations; ++i) + public static IEnumerable RunSByteExplicitCastFromBigIntegerTestSources + { + get { - VerifySByteExplicitCastFromBigInteger((sbyte)s_random.Next(1, sbyte.MaxValue)); + yield return new object[] { new BigInteger(sbyte.MinValue), sbyte.MinValue }; + yield return new object[] { new BigInteger(sbyte.MaxValue), sbyte.MaxValue }; + yield return new object[] { new BigInteger(-1), -1 }; + yield return new object[] { new BigInteger(0), 0 }; + yield return new object[] { new BigInteger(1), 1 }; + for (int i = 0; i < NumberOfRandomIterations; i++) + { + sbyte currentValue = (sbyte)s_random.Next(sbyte.MinValue, sbyte.MaxValue); + yield return new object[] { new BigInteger(currentValue), currentValue }; + } } - - // SByte Explicit Cast from BigInteger: SByte.MaxValue - VerifySByteExplicitCastFromBigInteger(sbyte.MaxValue); - - // SByte Explicit Cast from BigInteger: SByte.MaxValue + 1 - bigInteger = new BigInteger(sbyte.MaxValue); - bigInteger += BigInteger.One; - value = unchecked((sbyte)bigInteger.ToByteArray()[0]); - Assert.Throws(() => VerifySByteExplicitCastFromBigInteger(value, bigInteger)); - - // SByte Explicit Cast from BigInteger: Random value > SByte.MaxValue - bigInteger = GenerateRandomBigIntegerGreaterThan((ulong)sbyte.MaxValue, s_random); - value = unchecked((sbyte)bigInteger.ToByteArray()[0]); - Assert.Throws(() => VerifySByteExplicitCastFromBigInteger(value, bigInteger)); } - [Fact] - public static void RunUInt16ExplicitCastFromBigIntegerTests() + [Theory] + [MemberData(nameof(RunSByteExplicitCastFromBigIntegerTestSources))] + public void RunSByteExplicitCastFromBigIntegerTest(BigInteger testValue, sbyte expectedValue) { - ushort value; - BigInteger bigInteger; - - // UInt16 Explicit Cast from BigInteger: Random value < UInt16.MinValue - bigInteger = GenerateRandomBigIntegerLessThan(ushort.MinValue, s_random); - value = BitConverter.ToUInt16(ByteArrayMakeMinSize(bigInteger.ToByteArray(), 2), 0); - Assert.Throws(() => VerifyUInt16ExplicitCastFromBigInteger(value, bigInteger)); - - // UInt16 Explicit Cast from BigInteger: UInt16.MinValue - 1 - bigInteger = new BigInteger(ushort.MinValue); - bigInteger -= BigInteger.One; - value = BitConverter.ToUInt16(new byte[] { 0xff, 0xff }, 0); - Assert.Throws(() => VerifyUInt16ExplicitCastFromBigInteger(value, bigInteger)); + sbyte actualValue; - // UInt16 Explicit Cast from BigInteger: UInt16.MinValue - VerifyUInt16ExplicitCastFromBigInteger(ushort.MinValue); + actualValue = (sbyte)testValue; - // UInt16 Explicit Cast from BigInteger: 0 - VerifyUInt16ExplicitCastFromBigInteger(0); - - // UInt16 Explicit Cast from BigInteger: 1 - VerifyUInt16ExplicitCastFromBigInteger(1); + Assert.Equal(expectedValue, actualValue); + } - // UInt16 Explicit Cast from BigInteger: Random Positive - for (int i = 0; i < NumberOfRandomIterations; ++i) + public static IEnumerable RunSByteExplicitCastFromBigIntegerThrowsOverflowExceptionTestSources + { + get { - VerifyUInt16ExplicitCastFromBigInteger((ushort)s_random.Next(1, ushort.MaxValue)); + yield return new object[] { sbyte.MinValue - BigInteger.One }; + yield return new object[] { sbyte.MaxValue + BigInteger.One }; + yield return new object[] { GenerateRandomBigIntegerLessThan(sbyte.MinValue, s_random) }; + yield return new object[] { GenerateRandomBigIntegerGreaterThan((ulong)sbyte.MaxValue, s_random) }; } - - // UInt16 Explicit Cast from BigInteger: UInt16.MaxValue - VerifyUInt16ExplicitCastFromBigInteger(ushort.MaxValue); - - // UInt16 Explicit Cast from BigInteger: UInt16.MaxValue + 1 - bigInteger = new BigInteger(ushort.MaxValue); - bigInteger += BigInteger.One; - value = BitConverter.ToUInt16(bigInteger.ToByteArray(), 0); - Assert.Throws(() => VerifyUInt16ExplicitCastFromBigInteger(value, bigInteger)); - - // UInt16 Explicit Cast from BigInteger: Random value > UInt16.MaxValue - bigInteger = GenerateRandomBigIntegerGreaterThan(ushort.MaxValue, s_random); - value = BitConverter.ToUInt16(bigInteger.ToByteArray(), 0); - Assert.Throws(() => VerifyUInt16ExplicitCastFromBigInteger(value, bigInteger)); } - [Fact] - public static void RunInt16ExplicitCastFromBigIntegerTests() + [Theory] + [MemberData(nameof(RunSByteExplicitCastFromBigIntegerThrowsOverflowExceptionTestSources))] + public void RunSByteExplicitCastFromBigIntegerThrowsOverflowExceptionTest(BigInteger testValue) { - short value; - BigInteger bigInteger; - - // Int16 Explicit Cast from BigInteger: Random value < Int16.MinValue - bigInteger = GenerateRandomBigIntegerLessThan(short.MinValue, s_random); - value = BitConverter.ToInt16(bigInteger.ToByteArray(), 0); - Assert.Throws(() => VerifyInt16ExplicitCastFromBigInteger(value, bigInteger)); - - // Int16 Explicit Cast from BigInteger: Int16.MinValue - 1 - bigInteger = new BigInteger(short.MinValue); - bigInteger -= BigInteger.One; - value = BitConverter.ToInt16(bigInteger.ToByteArray(), 0); - Assert.Throws(() => VerifyInt16ExplicitCastFromBigInteger(value, bigInteger)); - - // Int16 Explicit Cast from BigInteger: Int16.MinValue - VerifyInt16ExplicitCastFromBigInteger(short.MinValue); + Assert.Throws(() => (sbyte)testValue); + } - // Int16 Explicit Cast from BigInteger: Random Negative - for (int i = 0; i < NumberOfRandomIterations; ++i) + public static IEnumerable RunUInt16ExplicitCastFromBigIntegerTestSources + { + get { - VerifyInt16ExplicitCastFromBigInteger((short)s_random.Next(short.MinValue, 0)); + yield return new object[] { new BigInteger(ushort.MinValue), ushort.MinValue }; + yield return new object[] { new BigInteger(ushort.MaxValue), ushort.MaxValue }; + yield return new object[] { new BigInteger(0), 0 }; + yield return new object[] { new BigInteger(1), 1 }; + for (int i = 0; i < NumberOfRandomIterations; i++) + { + ushort currentValue = (ushort)s_random.Next(ushort.MinValue, ushort.MaxValue); + yield return new object[] { new BigInteger(currentValue), currentValue }; + } } + } - // Int16 Explicit Cast from BigInteger: -1 - VerifyInt16ExplicitCastFromBigInteger(-1); + [Theory] + [MemberData(nameof(RunUInt16ExplicitCastFromBigIntegerTestSources))] + public void RunUInt16ExplicitCastFromBigIntegerTest(BigInteger testValue, ushort expectedValue) + { + ushort actualValue; - // Int16 Explicit Cast from BigInteger: 0 - VerifyInt16ExplicitCastFromBigInteger(0); + actualValue = (ushort)testValue; - // Int16 Explicit Cast from BigInteger: 1 - VerifyInt16ExplicitCastFromBigInteger(1); + Assert.Equal(expectedValue, actualValue); + } - // Int16 Explicit Cast from BigInteger: Random Positive - for (int i = 0; i < NumberOfRandomIterations; ++i) + public static IEnumerable RunUInt16ExplicitCastFromBigIntegerThrowsOverflowExceptionTestSources + { + get { - VerifyInt16ExplicitCastFromBigInteger((short)s_random.Next(1, short.MaxValue)); + yield return new object[] { ushort.MinValue - BigInteger.One }; + yield return new object[] { ushort.MaxValue + BigInteger.One }; + yield return new object[] { GenerateRandomBigIntegerLessThan(ushort.MinValue, s_random) }; + yield return new object[] { GenerateRandomBigIntegerGreaterThan(ushort.MaxValue, s_random) }; } - - // Int16 Explicit Cast from BigInteger: Int16.MaxValue - VerifyInt16ExplicitCastFromBigInteger(short.MaxValue); - - // Int16 Explicit Cast from BigInteger: Int16.MaxValue + 1 - bigInteger = new BigInteger(short.MaxValue); - bigInteger += BigInteger.One; - value = BitConverter.ToInt16(bigInteger.ToByteArray(), 0); - Assert.Throws(() => VerifyInt16ExplicitCastFromBigInteger(value, bigInteger)); - - // Int16 Explicit Cast from BigInteger: Random value > Int16.MaxValue - bigInteger = GenerateRandomBigIntegerGreaterThan((ulong)short.MaxValue, s_random); - value = BitConverter.ToInt16(bigInteger.ToByteArray(), 0); - Assert.Throws(() => VerifyInt16ExplicitCastFromBigInteger(value, bigInteger)); } - [Fact] - public static void RunUInt32ExplicitCastFromBigIntegerTests() + [Theory] + [MemberData(nameof(RunUInt16ExplicitCastFromBigIntegerThrowsOverflowExceptionTestSources))] + public void RunUInt16ExplicitCastFromBigIntegerThrowsOverflowExceptionTest(BigInteger testValue) { - uint value; - BigInteger bigInteger; - - // UInt32 Explicit Cast from BigInteger: Random value < UInt32.MinValue - bigInteger = GenerateRandomBigIntegerLessThan(uint.MinValue, s_random); - value = BitConverter.ToUInt32(ByteArrayMakeMinSize(bigInteger.ToByteArray(), 4), 0); - Assert.Throws(() => VerifyUInt32ExplicitCastFromBigInteger(value, bigInteger)); - - // UInt32 Explicit Cast from BigInteger: UInt32.MinValue - 1 - bigInteger = new BigInteger(uint.MinValue); - bigInteger -= BigInteger.One; - value = BitConverter.ToUInt32(new byte[] { 0xff, 0xff, 0xff, 0xff }, 0); - Assert.Throws(() => VerifyUInt32ExplicitCastFromBigInteger(value, bigInteger)); - - // UInt32 Explicit Cast from BigInteger: UInt32.MinValue - VerifyUInt32ExplicitCastFromBigInteger(uint.MinValue); - - // UInt32 Explicit Cast from BigInteger: 0 - VerifyUInt32ExplicitCastFromBigInteger(0); - - // UInt32 Explicit Cast from BigInteger: 1 - VerifyUInt32ExplicitCastFromBigInteger(1); + Assert.Throws(() => (ushort)testValue); + } - // UInt32 Explicit Cast from BigInteger: Random Positive - for (int i = 0; i < NumberOfRandomIterations; ++i) + public static IEnumerable RunInt16ExplicitCastFromBigIntegerTestSources + { + get { - VerifyUInt32ExplicitCastFromBigInteger((uint)(uint.MaxValue * s_random.NextDouble())); + yield return new object[] { new BigInteger(short.MinValue), short.MinValue }; + yield return new object[] { new BigInteger(short.MaxValue), short.MaxValue }; + yield return new object[] { new BigInteger(-1), -1 }; + yield return new object[] { new BigInteger(0), 0 }; + yield return new object[] { new BigInteger(1), 1 }; + for (int i = 0; i < NumberOfRandomIterations; i++) + { + short currentValue = (short)s_random.Next(short.MinValue, short.MaxValue); + yield return new object[] { new BigInteger(currentValue), currentValue }; + } } - - // UInt32 Explicit Cast from BigInteger: UInt32.MaxValue - VerifyUInt32ExplicitCastFromBigInteger(uint.MaxValue); - - // UInt32 Explicit Cast from BigInteger: UInt32.MaxValue + 1 - bigInteger = new BigInteger(uint.MaxValue); - bigInteger += BigInteger.One; - value = BitConverter.ToUInt32(bigInteger.ToByteArray(), 0); - Assert.Throws(() => VerifyUInt32ExplicitCastFromBigInteger(value, bigInteger)); - - // UInt32 Explicit Cast from BigInteger: Random value > UInt32.MaxValue - bigInteger = GenerateRandomBigIntegerGreaterThan(uint.MaxValue, s_random); - value = BitConverter.ToUInt32(bigInteger.ToByteArray(), 0); - Assert.Throws(() => VerifyUInt32ExplicitCastFromBigInteger(value, bigInteger)); } - [Fact] - public static void RunInt32ExplicitCastFromBigIntegerTests() + [Theory] + [MemberData(nameof(RunInt16ExplicitCastFromBigIntegerTestSources))] + public void RunInt16ExplicitCastFromBigIntegerTest(BigInteger testValue, short expectedValue) { - int value; - BigInteger bigInteger; + short actualValue; - // Int32 Explicit Cast from BigInteger: Random value < Int32.MinValue - bigInteger = GenerateRandomBigIntegerLessThan(int.MinValue, s_random); - value = BitConverter.ToInt32(bigInteger.ToByteArray(), 0); - Assert.Throws(() => VerifyInt32ExplicitCastFromBigInteger(value, bigInteger)); + actualValue = (short)testValue; - // Int32 Explicit Cast from BigInteger: Int32.MinValue - 1 - bigInteger = new BigInteger(int.MinValue); - bigInteger -= BigInteger.One; - value = BitConverter.ToInt32(bigInteger.ToByteArray(), 0); - Assert.Throws(() => VerifyInt32ExplicitCastFromBigInteger(value, bigInteger)); - - // Int32 Explicit Cast from BigInteger: Int32.MinValue - VerifyInt32ExplicitCastFromBigInteger(int.MinValue); + Assert.Equal(expectedValue, actualValue); + } - // Int32 Explicit Cast from BigInteger: Random Negative - for (int i = 0; i < NumberOfRandomIterations; ++i) + public static IEnumerable RunInt16ExplicitCastFromBigIntegerThrowsOverflowExceptionTestSources + { + get { - VerifyInt32ExplicitCastFromBigInteger((int)s_random.Next(int.MinValue, 0)); + yield return new object[] { short.MinValue - BigInteger.One }; + yield return new object[] { short.MaxValue + BigInteger.One }; + yield return new object[] { GenerateRandomBigIntegerLessThan(short.MinValue, s_random) }; + yield return new object[] { GenerateRandomBigIntegerGreaterThan((long)short.MaxValue, s_random) }; } + } - // Int32 Explicit Cast from BigInteger: -1 - VerifyInt32ExplicitCastFromBigInteger(-1); - - // Int32 Explicit Cast from BigInteger: 0 - VerifyInt32ExplicitCastFromBigInteger(0); - - // Int32 Explicit Cast from BigInteger: 1 - VerifyInt32ExplicitCastFromBigInteger(1); + [Theory] + [MemberData(nameof(RunInt16ExplicitCastFromBigIntegerThrowsOverflowExceptionTestSources))] + public void RunInt16ExplicitCastFromBigIntegerThrowsOverflowExceptionTest(BigInteger testValue) + { + Assert.Throws(() => (short)testValue); + } - // Int32 Explicit Cast from BigInteger: Random Positive - for (int i = 0; i < NumberOfRandomIterations; ++i) + public static IEnumerable RunUInt32ExplicitCastFromBigIntegerTestSources + { + get { - VerifyInt32ExplicitCastFromBigInteger((int)s_random.Next(1, int.MaxValue)); + yield return new object[] { new BigInteger(uint.MinValue), uint.MinValue }; + yield return new object[] { new BigInteger(uint.MaxValue), uint.MaxValue }; + yield return new object[] { new BigInteger(0), 0 }; + yield return new object[] { new BigInteger(1), 1 }; + for (int i = 0; i < NumberOfRandomIterations; i++) + { + uint currentValue = (uint)(uint.MaxValue * s_random.NextDouble()); + yield return new object[] { new BigInteger(currentValue), currentValue }; + } } - - // Int32 Explicit Cast from BigInteger: Int32.MaxValue - VerifyInt32ExplicitCastFromBigInteger(int.MaxValue); - - // Int32 Explicit Cast from BigInteger: Int32.MaxValue + 1 - bigInteger = new BigInteger(int.MaxValue); - bigInteger += BigInteger.One; - value = BitConverter.ToInt32(bigInteger.ToByteArray(), 0); - Assert.Throws(() => VerifyInt32ExplicitCastFromBigInteger(value, bigInteger)); - - // Int32 Explicit Cast from BigInteger: Random value > Int32.MaxValue - bigInteger = GenerateRandomBigIntegerGreaterThan(int.MaxValue, s_random); - value = BitConverter.ToInt32(bigInteger.ToByteArray(), 0); - Assert.Throws(() => VerifyInt32ExplicitCastFromBigInteger(value, bigInteger)); } - [Fact] - public static void RunUInt64ExplicitCastFromBigIntegerTests() + [Theory] + [MemberData(nameof(RunUInt32ExplicitCastFromBigIntegerTestSources))] + public void RunUInt32ExplicitCastFromBigIntegerTest(BigInteger testValue, uint expectedValue) { - ulong value; - BigInteger bigInteger; + uint actualValue; - // UInt64 Explicit Cast from BigInteger: Random value < UInt64.MinValue - bigInteger = GenerateRandomBigIntegerLessThan(0, s_random); - value = BitConverter.ToUInt64(ByteArrayMakeMinSize(bigInteger.ToByteArray(), 8), 0); - Assert.Throws(() => VerifyUInt64ExplicitCastFromBigInteger(value, bigInteger)); + actualValue = (uint)testValue; - // UInt64 Explicit Cast from BigInteger: UInt64.MinValue - 1 - bigInteger = new BigInteger(ulong.MinValue); - bigInteger -= BigInteger.One; - value = BitConverter.ToUInt64(new byte[] { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 0); - Assert.Throws(() => VerifyUInt64ExplicitCastFromBigInteger(value, bigInteger)); - - // UInt64 Explicit Cast from BigInteger: UInt64.MinValue - VerifyUInt64ExplicitCastFromBigInteger(ulong.MinValue); - - // UInt64 Explicit Cast from BigInteger: 0 - VerifyUInt64ExplicitCastFromBigInteger(0); - - // UInt64 Explicit Cast from BigInteger: 1 - VerifyUInt64ExplicitCastFromBigInteger(1); + Assert.Equal(expectedValue, actualValue); + } - // UInt64 Explicit Cast from BigInteger: Random Positive - for (int i = 0; i < NumberOfRandomIterations; ++i) + public static IEnumerable RunUInt32ExplicitCastFromBigIntegerThrowsOverflowExceptionTestSources + { + get { - VerifyUInt64ExplicitCastFromBigInteger((ulong)(ulong.MaxValue * s_random.NextDouble())); + yield return new object[] { uint.MinValue - BigInteger.One }; + yield return new object[] { uint.MaxValue + BigInteger.One }; + yield return new object[] { GenerateRandomBigIntegerLessThan(uint.MinValue, s_random) }; + yield return new object[] { GenerateRandomBigIntegerGreaterThan(uint.MaxValue, s_random) }; } - - // UInt64 Explicit Cast from BigInteger: UInt64.MaxValue - VerifyUInt64ExplicitCastFromBigInteger(ulong.MaxValue); - - // UInt64 Explicit Cast from BigInteger: UInt64.MaxValue + 1 - bigInteger = new BigInteger(ulong.MaxValue); - bigInteger += BigInteger.One; - value = BitConverter.ToUInt64(bigInteger.ToByteArray(), 0); - Assert.Throws(() => VerifyUInt64ExplicitCastFromBigInteger(value, bigInteger)); - - // UInt64 Explicit Cast from BigInteger: Random value > UInt64.MaxValue - bigInteger = GenerateRandomBigIntegerGreaterThan(ulong.MaxValue, s_random); - value = BitConverter.ToUInt64(bigInteger.ToByteArray(), 0); - Assert.Throws(() => VerifyUInt64ExplicitCastFromBigInteger(value, bigInteger)); } - [Fact] - public static void RunInt64ExplicitCastFromBigIntegerTests() + [Theory] + [MemberData(nameof(RunUInt32ExplicitCastFromBigIntegerThrowsOverflowExceptionTestSources))] + public void RunUInt32ExplicitCastFromBigIntegerThrowsOverflowExceptionTest(BigInteger testValue) { - long value; - BigInteger bigInteger; - - // Int64 Explicit Cast from BigInteger: Random value < Int64.MinValue - bigInteger = GenerateRandomBigIntegerLessThan(long.MinValue, s_random); - value = BitConverter.ToInt64(bigInteger.ToByteArray(), 0); - Assert.Throws(() => VerifyInt64ExplicitCastFromBigInteger(value, bigInteger)); - - // Int64 Explicit Cast from BigInteger: Int64.MinValue - 1 - bigInteger = new BigInteger(long.MinValue); - bigInteger -= BigInteger.One; - value = BitConverter.ToInt64(bigInteger.ToByteArray(), 0); - Assert.Throws(() => VerifyInt64ExplicitCastFromBigInteger(value, bigInteger)); - - // Int64 Explicit Cast from BigInteger: Int64.MinValue - VerifyInt64ExplicitCastFromBigInteger(long.MinValue); + Assert.Throws(() => (uint)testValue); + } - // Int64 Explicit Cast from BigInteger: Random Negative - for (int i = 0; i < NumberOfRandomIterations; ++i) + public static IEnumerable RunInt32ExplicitCastFromBigIntegerTestSources + { + get { - VerifyInt64ExplicitCastFromBigInteger(((long)(long.MaxValue * s_random.NextDouble())) - long.MaxValue); + yield return new object[] { new BigInteger(int.MinValue), int.MinValue }; + yield return new object[] { new BigInteger(int.MaxValue), int.MaxValue }; + yield return new object[] { new BigInteger(-1), -1 }; + yield return new object[] { new BigInteger(0), 0 }; + yield return new object[] { new BigInteger(1), 1 }; + for (int i = 0; i < NumberOfRandomIterations; i++) + { + int currentValue = s_random.Next(int.MinValue, int.MaxValue); + yield return new object[] { new BigInteger(currentValue), currentValue }; + } } + } - // Int64 Explicit Cast from BigInteger: -1 - VerifyInt64ExplicitCastFromBigInteger(-1); + [Theory] + [MemberData(nameof(RunInt32ExplicitCastFromBigIntegerTestSources))] + public void RunInt32ExplicitCastFromBigIntegerTest(BigInteger testValue, int expectedValue) + { + int actualValue; - // Int64 Explicit Cast from BigInteger: 0 - VerifyInt64ExplicitCastFromBigInteger(0); + actualValue = (int)testValue; - // Int64 Explicit Cast from BigInteger: 1 - VerifyInt64ExplicitCastFromBigInteger(1); + Assert.Equal(expectedValue, actualValue); + } - // Int64 Explicit Cast from BigInteger: Random Positive - for (int i = 0; i < NumberOfRandomIterations; ++i) + public static IEnumerable RunInt32ExplicitCastFromBigIntegerThrowsOverflowExceptionTestSources + { + get { - VerifyInt64ExplicitCastFromBigInteger((long)(long.MaxValue * s_random.NextDouble())); + yield return new object[] { int.MinValue - BigInteger.One }; + yield return new object[] { int.MaxValue + BigInteger.One }; + yield return new object[] { GenerateRandomBigIntegerLessThan(int.MinValue, s_random) }; + yield return new object[] { GenerateRandomBigIntegerGreaterThan(int.MaxValue, s_random) }; } - - // Int64 Explicit Cast from BigInteger: Int64.MaxValue - VerifyInt64ExplicitCastFromBigInteger(long.MaxValue); - - // Int64 Explicit Cast from BigInteger: Int64.MaxValue + 1 - bigInteger = new BigInteger(long.MaxValue); - bigInteger += BigInteger.One; - value = BitConverter.ToInt64(bigInteger.ToByteArray(), 0); - Assert.Throws(() => VerifyInt64ExplicitCastFromBigInteger(value, bigInteger)); - - // Int64 Explicit Cast from BigInteger: Random value > Int64.MaxValue - bigInteger = GenerateRandomBigIntegerGreaterThan(long.MaxValue, s_random); - value = BitConverter.ToInt64(bigInteger.ToByteArray(), 0); - Assert.Throws(() => VerifyInt64ExplicitCastFromBigInteger(value, bigInteger)); } - [Fact] - public static void RunSingleExplicitCastFromBigIntegerTests() + [Theory] + [MemberData(nameof(RunInt32ExplicitCastFromBigIntegerThrowsOverflowExceptionTestSources))] + public void RunInt32ExplicitCastFromBigIntegerThrowsOverflowExceptionTest(BigInteger testValue) { - BigInteger bigInteger; - - // Single Explicit Cast from BigInteger: Random value < Single.MinValue - bigInteger = GenerateRandomBigIntegerLessThan(float.MinValue * 2.0, s_random); - VerifySingleExplicitCastFromBigInteger(float.NegativeInfinity, bigInteger); - - // Single Explicit Cast from BigInteger: Single.MinValue - 1 - bigInteger = new BigInteger(float.MinValue); - bigInteger -= BigInteger.One; - VerifySingleExplicitCastFromBigInteger(float.MinValue, bigInteger); - - // Single Explicit Cast from BigInteger: Single.MinValue - VerifySingleExplicitCastFromBigInteger(float.MinValue); - - // Single Explicit Cast from BigInteger: Random Negative - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifySingleExplicitCastFromBigInteger(((float)(float.MaxValue * s_random.NextDouble())) - float.MaxValue); - } + Assert.Throws(() => (int)testValue); + } - // Single Explicit Cast from BigInteger: Random Negative Non-integral > -100 - for (int i = 0; i < NumberOfRandomIterations; ++i) + public static IEnumerable RunUInt64ExplicitCastFromBigIntegerTestSources + { + get { - VerifySingleExplicitCastFromBigInteger(((float)(100 * s_random.NextDouble())) - 100); + yield return new object[] { new BigInteger(ulong.MinValue), ulong.MinValue }; + yield return new object[] { new BigInteger(ulong.MaxValue), ulong.MaxValue }; + yield return new object[] { new BigInteger(0), 0 }; + yield return new object[] { new BigInteger(1), 1 }; + for (int i = 0; i < NumberOfRandomIterations; i++) + { + ulong currentValue = (ulong)(ulong.MaxValue * s_random.NextDouble()); + yield return new object[] { new BigInteger(currentValue), currentValue }; + } } + } - // Single Explicit Cast from BigInteger: -1 - VerifySingleExplicitCastFromBigInteger(-1); - - // Single Explicit Cast from BigInteger: 0 - VerifySingleExplicitCastFromBigInteger(0); + [Theory] + [MemberData(nameof(RunUInt64ExplicitCastFromBigIntegerTestSources))] + public void RunUInt64ExplicitCastFromBigIntegerTest(BigInteger testValue, ulong expectedValue) + { + ulong actualValue; - // Single Explicit Cast from BigInteger: 1 - VerifySingleExplicitCastFromBigInteger(1); + actualValue = (ulong)testValue; - // Single Explicit Cast from BigInteger: Random Positive Non-integral < 100 - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifySingleExplicitCastFromBigInteger((float)(100 * s_random.NextDouble())); - } + Assert.Equal(expectedValue, actualValue); + } - // Single Explicit Cast from BigInteger: Random Positive - for (int i = 0; i < NumberOfRandomIterations; ++i) + public static IEnumerable RunUInt64ExplicitCastFromBigIntegerThrowsOverflowExceptionTestSources + { + get { - VerifySingleExplicitCastFromBigInteger((float)(float.MaxValue * s_random.NextDouble())); + yield return new object[] { ulong.MinValue - BigInteger.One }; + yield return new object[] { ulong.MaxValue + BigInteger.One }; + yield return new object[] { GenerateRandomBigIntegerLessThan(0, s_random) }; + yield return new object[] { GenerateRandomBigIntegerGreaterThan(ulong.MaxValue, s_random) }; } - - // Single Explicit Cast from BigInteger: Single.MaxValue + 1 - bigInteger = new BigInteger(float.MaxValue); - bigInteger += BigInteger.One; - VerifySingleExplicitCastFromBigInteger(float.MaxValue, bigInteger); - - // Single Explicit Cast from BigInteger: Random value > Single.MaxValue - bigInteger = GenerateRandomBigIntegerGreaterThan((double)float.MaxValue * 2, s_random); - VerifySingleExplicitCastFromBigInteger(float.PositiveInfinity, bigInteger); - - // Single Explicit Cast from BigInteger: value < Single.MaxValue but can not be accurately represented in a Single - bigInteger = new BigInteger(16777217); - VerifySingleExplicitCastFromBigInteger(16777216f, bigInteger); - - // Single Explicit Cast from BigInteger: Single.MinValue < value but can not be accurately represented in a Single - bigInteger = new BigInteger(-16777217); - VerifySingleExplicitCastFromBigInteger(-16777216f, bigInteger); } - [Fact] - public static void RunDoubleExplicitCastFromBigIntegerTests() + [Theory] + [MemberData(nameof(RunUInt64ExplicitCastFromBigIntegerThrowsOverflowExceptionTestSources))] + public void RunUInt64ExplicitCastFromBigIntegerThrowsOverflowExceptionTest(BigInteger testValue) { - BigInteger bigInteger; - - // Double Explicit Cast from BigInteger: Random value < Double.MinValue - bigInteger = GenerateRandomBigIntegerLessThan(double.MinValue, s_random); - bigInteger *= 2; - VerifyDoubleExplicitCastFromBigInteger(double.NegativeInfinity, bigInteger); - - // Double Explicit Cast from BigInteger: Double.MinValue - 1 - bigInteger = new BigInteger(double.MinValue); - bigInteger -= BigInteger.One; - VerifyDoubleExplicitCastFromBigInteger(double.MinValue, bigInteger); - - // Double Explicit Cast from BigInteger: Double.MinValue - VerifyDoubleExplicitCastFromBigInteger(double.MinValue); - - // Double Explicit Cast from BigInteger: Random Negative - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifyDoubleExplicitCastFromBigInteger(((double)(double.MaxValue * s_random.NextDouble())) - double.MaxValue); - } + Assert.Throws(() => (ulong)testValue); + } - // Double Explicit Cast from BigInteger: Random Negative Non-integral > -100 - for (int i = 0; i < NumberOfRandomIterations; ++i) + public static IEnumerable RunInt64ExplicitCastFromBigIntegerTestSources + { + get { - VerifyDoubleExplicitCastFromBigInteger(((double)(100 * s_random.NextDouble())) - 100); + yield return new object[] { new BigInteger(long.MinValue), long.MinValue }; + yield return new object[] { new BigInteger(long.MaxValue), long.MaxValue }; + yield return new object[] { new BigInteger(-1), -1 }; + yield return new object[] { new BigInteger(0), 0 }; + yield return new object[] { new BigInteger(1), 1 }; + for (int i = 0; i < NumberOfRandomIterations; i++) + { + long currentValue = (long)(long.MinValue * s_random.NextDouble()); + yield return new object[] { new BigInteger(currentValue), currentValue }; + } + for (int i = 0; i < NumberOfRandomIterations; i++) + { + long currentValue = (long) (long.MaxValue * s_random.NextDouble()); + yield return new object[] { new BigInteger(currentValue), currentValue }; + } } + } - // Double Explicit Cast from BigInteger: -1 - VerifyDoubleExplicitCastFromBigInteger(-1); - - // Double Explicit Cast from BigInteger: 0 - VerifyDoubleExplicitCastFromBigInteger(0); + [Theory] + [MemberData(nameof(RunInt64ExplicitCastFromBigIntegerTestSources))] + public void RunInt64ExplicitCastFromBigIntegerTest(BigInteger testValue, long expectedValue) + { + long actualValue; - // Double Explicit Cast from BigInteger: 1 - VerifyDoubleExplicitCastFromBigInteger(1); + actualValue = (long)testValue; - // Double Explicit Cast from BigInteger: Random Positive Non-integral < 100 - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifyDoubleExplicitCastFromBigInteger((double)(100 * s_random.NextDouble())); - } + Assert.Equal(expectedValue, actualValue); + } - // Double Explicit Cast from BigInteger: Random Positive - for (int i = 0; i < NumberOfRandomIterations; ++i) + public static IEnumerable RunInt64ExplicitCastFromBigIntegerThrowsOverflowExceptionTestSources + { + get { - VerifyDoubleExplicitCastFromBigInteger((double)(double.MaxValue * s_random.NextDouble())); + yield return new object[] { long.MinValue - BigInteger.One }; + yield return new object[] { long.MaxValue + BigInteger.One }; + yield return new object[] { GenerateRandomBigIntegerLessThan(long.MinValue, s_random) }; + yield return new object[] { GenerateRandomBigIntegerGreaterThan(long.MaxValue, s_random) }; } - - // Double Explicit Cast from BigInteger: Double.MaxValue - VerifyDoubleExplicitCastFromBigInteger(double.MaxValue); - - // Double Explicit Cast from BigInteger: Double.MaxValue + 1 - bigInteger = new BigInteger(double.MaxValue); - bigInteger += BigInteger.One; - VerifyDoubleExplicitCastFromBigInteger(double.MaxValue, bigInteger); - - // Double Explicit Cast from BigInteger: Double.MinValue - 1 - bigInteger = new BigInteger(double.MinValue); - bigInteger -= BigInteger.One; - VerifyDoubleExplicitCastFromBigInteger(double.MinValue, bigInteger); - - // Double Explicit Cast from BigInteger: Random value > Double.MaxValue - bigInteger = GenerateRandomBigIntegerGreaterThan(double.MaxValue, s_random); - bigInteger *= 2; - VerifyDoubleExplicitCastFromBigInteger(double.PositiveInfinity, bigInteger); - - // Double Explicit Cast from BigInteger: Random value < -Double.MaxValue - VerifyDoubleExplicitCastFromBigInteger(double.NegativeInfinity, -bigInteger); - - // Double Explicit Cast from BigInteger: very large values (more than Int32.MaxValue bits) should be infinity - DoubleExplicitCastFromLargeBigIntegerTests(128, 1); - - // Double Explicit Cast from BigInteger: value < Double.MaxValue but can not be accurately represented in a Double - bigInteger = new BigInteger(9007199254740993); - VerifyDoubleExplicitCastFromBigInteger(9007199254740992, bigInteger); - - // Double Explicit Cast from BigInteger: Double.MinValue < value but can not be accurately represented in a Double - bigInteger = new BigInteger(-9007199254740993); - VerifyDoubleExplicitCastFromBigInteger(-9007199254740992, bigInteger); } - [Fact] - [OuterLoop] - public static void RunDoubleExplicitCastFromLargeBigIntegerTests() + [Theory] + [MemberData(nameof(RunInt64ExplicitCastFromBigIntegerThrowsOverflowExceptionTestSources))] + public void RunInt64ExplicitCastFromBigIntegerThrowsOverflowExceptionTest(BigInteger testValue) { - DoubleExplicitCastFromLargeBigIntegerTests(0, 4, 32, 3); + Assert.Throws(() => (long)testValue); } - [Fact] - public static void RunDecimalExplicitCastFromBigIntegerTests() + public static IEnumerable RunSingleExplicitCastFromBigIntegerTestSources { - int[] bits = new int[3]; - uint temp2; - bool carry; - byte[] temp; - decimal value; - BigInteger bigInteger; - - // Decimal Explicit Cast from BigInteger: Random value < Decimal.MinValue - for (int i = 0; i < NumberOfRandomIterations; ++i) + get { - bigInteger = GenerateRandomBigIntegerLessThan(decimal.MinValue, s_random); - temp = bigInteger.ToByteArray(); - carry = true; - for (int j = 0; j < 3; j++) + yield return new object[] { new BigInteger(float.MinValue), float.MinValue }; + yield return new object[] { new BigInteger(float.MaxValue), float.MaxValue }; +#if false + yield return new object[] { new BigInteger(float.MinValue) - BigInteger.One, float.NegativeInfinity }; + yield return new object[] { new BigInteger(float.MaxValue) + BigInteger.One, float.PositiveInfinity }; +#endif + yield return new object[] { new BigInteger(-1f), -1f }; + yield return new object[] { new BigInteger(0f), 0f }; + yield return new object[] { new BigInteger(1f), 1f }; + for (int i = 0; i < NumberOfRandomIterations; i++) { - temp2 = BitConverter.ToUInt32(temp, 4 * j); - temp2 = ~temp2; - if (carry) - { - carry = false; - temp2 += 1; - if (temp2 == 0) - { - carry = true; - } - } - bits[j] = unchecked((int)temp2); + float currentValue = (float)(float.MinValue * s_random.NextDouble()); + yield return new object[] { new BigInteger(currentValue), currentValue }; } - value = new decimal(bits[0], bits[1], bits[2], true, 0); - Assert.Throws(() => VerifyDecimalExplicitCastFromBigInteger(value, bigInteger)); - } - - // Decimal Explicit Cast from BigInteger: Decimal.MinValue - 1 - bigInteger = new BigInteger(decimal.MinValue); - bigInteger -= BigInteger.One; - temp = bigInteger.ToByteArray(); - carry = true; - for (int j = 0; j < 3; j++) - { - temp2 = BitConverter.ToUInt32(temp, 4 * j); - temp2 = ~temp2; - if (carry) + for (int i = 0; i < NumberOfRandomIterations; i++) { - carry = false; - temp2 = unchecked(temp2 + 1); - if (temp2 == 0) - { - carry = true; - } + float currentValue = (float)(float.MaxValue * s_random.NextDouble()); + yield return new object[] { new BigInteger(currentValue), currentValue }; } - bits[j] = (int)temp2; - } - value = new decimal(bits[0], bits[1], bits[2], true, 0); - Assert.Throws(() => VerifyDecimalExplicitCastFromBigInteger(value, bigInteger)); - - // Decimal Explicit Cast from BigInteger: Decimal.MinValue - VerifyDecimalExplicitCastFromBigInteger(decimal.MinValue); - - // Decimal Explicit Cast from BigInteger: Random Negative - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifyDecimalExplicitCastFromBigInteger(((decimal)((double)decimal.MaxValue * s_random.NextDouble())) - decimal.MaxValue); - } - - // Decimal Explicit Cast from BigInteger: Random Negative Non-Integral > -100 - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - value = (decimal)(100 * s_random.NextDouble() - 100); - VerifyDecimalExplicitCastFromBigInteger(decimal.Truncate(value), new BigInteger(value)); } + } - // Decimal Explicit Cast from BigInteger: -1 - VerifyDecimalExplicitCastFromBigInteger(-1); + [Theory] + [MemberData(nameof(RunSingleExplicitCastFromBigIntegerTestSources))] + public void RunSingleExplicitCastFromBigIntegerTest(BigInteger testValue, float expectedValue) + { + float actualValue; - // Decimal Explicit Cast from BigInteger: 0 - VerifyDecimalExplicitCastFromBigInteger(0); + actualValue = (float)testValue; - // Decimal Explicit Cast from BigInteger: 1 - VerifyDecimalExplicitCastFromBigInteger(1); + Assert.Equal(expectedValue, actualValue); + } - // Decimal Explicit Cast from BigInteger: Random Positive Non-Integral < 100 - for (int i = 0; i < NumberOfRandomIterations; ++i) + public static IEnumerable RunDoubleExplicitCastFromBigIntegerTestSources + { + get { - value = (decimal)(100 * s_random.NextDouble()); - VerifyDecimalExplicitCastFromBigInteger(decimal.Truncate(value), new BigInteger(value)); + yield return new object[] { new BigInteger(double.MinValue), double.MinValue }; + yield return new object[] { new BigInteger(double.MaxValue), double.MaxValue }; +#if false + yield return new object[] { new BigInteger(double.MinValue) - BigInteger.One, double.NegativeInfinity }; + yield return new object[] { new BigInteger(double.MaxValue) + BigInteger.One, double.PositiveInfinity }; +#endif + yield return new object[] { new BigInteger(-1.0), -1.0 }; + yield return new object[] { new BigInteger(0.0), 0.0 }; + yield return new object[] { new BigInteger(1.0), 1.0 }; + for (int i = 0; i < NumberOfRandomIterations; i++) + { + double currentValue = double.MinValue * s_random.NextDouble(); + yield return new object[] { new BigInteger(currentValue), currentValue }; + } + for (int i = 0; i < NumberOfRandomIterations; i++) + { + double currentValue = double.MaxValue * s_random.NextDouble(); + yield return new object[] { new BigInteger(currentValue), currentValue }; + } } + } - // Decimal Explicit Cast from BigInteger: Random Positive - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifyDecimalExplicitCastFromBigInteger((decimal)((double)decimal.MaxValue * s_random.NextDouble())); - } + [Theory] + [MemberData(nameof(RunDoubleExplicitCastFromBigIntegerTestSources))] + public void RunDoubleExplicitCastFromBigIntegerTest(BigInteger testValue, double expectedValue) + { + double actualValue; - // Decimal Explicit Cast from BigInteger: Decimal.MaxValue - VerifyDecimalExplicitCastFromBigInteger(decimal.MaxValue); + actualValue = (double)testValue; - // Decimal Explicit Cast from BigInteger: Decimal.MaxValue + 1 - bigInteger = new BigInteger(decimal.MaxValue); - bigInteger += BigInteger.One; - temp = bigInteger.ToByteArray(); - for (int j = 0; j < 3; j++) - { - bits[j] = BitConverter.ToInt32(temp, 4 * j); - } - value = new decimal(bits[0], bits[1], bits[2], false, 0); - Assert.Throws(() => VerifyDecimalExplicitCastFromBigInteger(value, bigInteger)); + Assert.Equal(expectedValue, actualValue); + } - // Decimal Explicit Cast from BigInteger: Random value > Decimal.MaxValue - for (int i = 0; i < NumberOfRandomIterations; ++i) + public static IEnumerable RunDecimalExplicitCastFromBigIntegerTestSources + { + get { - bigInteger = GenerateRandomBigIntegerGreaterThan(decimal.MaxValue, s_random); - temp = bigInteger.ToByteArray(); - for (int j = 0; j < 3; j++) + yield return new object[] { new BigInteger(decimal.MinValue), decimal.MinValue }; + yield return new object[] { new BigInteger(decimal.MaxValue), decimal.MaxValue }; + yield return new object[] { new BigInteger(-1.0), -1.0 }; + yield return new object[] { new BigInteger(0.0), 0.0 }; + yield return new object[] { new BigInteger(1.0), 1.0 }; + for (int i = 0; i < NumberOfRandomIterations; i++) { - bits[j] = BitConverter.ToInt32(temp, 4 * j); + decimal currentValue = (decimal)((double)decimal.MinValue * s_random.NextDouble()); + yield return new object[] { new BigInteger(currentValue), currentValue }; + } + for (int i = 0; i < NumberOfRandomIterations; i++) + { + decimal currentValue = (decimal)((double)decimal.MaxValue * s_random.NextDouble()); + yield return new object[] { new BigInteger(currentValue), currentValue }; } - value = new decimal(bits[0], bits[1], bits[2], false, 0); - Assert.Throws(() => VerifyDecimalExplicitCastFromBigInteger(value, bigInteger)); } } - /// - /// Test cast to Double on Very Large BigInteger more than (1 << Int.MaxValue) - /// Tested BigInteger are: +/-pow(2, startShift + smallLoopShift * [1..smallLoopLimit] + Int32.MaxValue * [1..bigLoopLimit]) - /// Expected double is positive and negative infinity - /// Note: - /// ToString() can not operate such large values - /// - private static void DoubleExplicitCastFromLargeBigIntegerTests(int startShift, int bigShiftLoopLimit, int smallShift = 0, int smallShiftLoopLimit = 1) + [Theory] + [MemberData(nameof(RunDecimalExplicitCastFromBigIntegerTestSources))] + public void RunDecimalExplicitCastFromBigIntegerTest(BigInteger testValue, decimal expectedValue) { - BigInteger init = BigInteger.One << startShift; + decimal actualValue; - for (int i = 0; i < smallShiftLoopLimit; i++) - { - BigInteger temp = init << ((i + 1) * smallShift); + actualValue = (decimal)testValue; - for (int j = 0; j < bigShiftLoopLimit; j++) - { - temp = temp << (int.MaxValue / 10); - VerifyDoubleExplicitCastFromBigInteger(double.PositiveInfinity, temp); - VerifyDoubleExplicitCastFromBigInteger(double.NegativeInfinity, -temp); - } - } + Assert.Equal(expectedValue, actualValue); } private static BigInteger GenerateRandomNegativeBigInteger(Random random) @@ -735,7 +493,7 @@ private static BigInteger GenerateRandomNegativeBigInteger(Random random) int arraySize = random.Next(1, 8) * 4; byte[] byteArray = new byte[arraySize]; - for (int i = 0; i < arraySize; ++i) + for (int i = 0; i < arraySize; i++) { byteArray[i] = (byte)random.Next(0, 256); } @@ -752,7 +510,7 @@ private static BigInteger GenerateRandomPositiveBigInteger(Random random) int arraySize = random.Next(1, 8) * 4; byte[] byteArray = new byte[arraySize]; - for (int i = 0; i < arraySize; ++i) + for (int i = 0; i < arraySize; i++) { byteArray[i] = (byte)random.Next(0, 256); } @@ -768,163 +526,9 @@ private static BigInteger GenerateRandomBigIntegerLessThan(long value, Random ra return (GenerateRandomNegativeBigInteger(random) + value) - 1; } - private static BigInteger GenerateRandomBigIntegerLessThan(double value, Random random) - { - return (GenerateRandomNegativeBigInteger(random) + (BigInteger)value) - 1; - } - - private static BigInteger GenerateRandomBigIntegerLessThan(decimal value, Random random) - { - return (GenerateRandomNegativeBigInteger(random) + (BigInteger)value) - 1; - } - private static BigInteger GenerateRandomBigIntegerGreaterThan(ulong value, Random random) { return (GenerateRandomPositiveBigInteger(random) + value) + 1; } - - private static BigInteger GenerateRandomBigIntegerGreaterThan(double value, Random random) - { - return (GenerateRandomPositiveBigInteger(random) + (BigInteger)value) + 1; - } - - private static BigInteger GenerateRandomBigIntegerGreaterThan(decimal value, Random random) - { - return (GenerateRandomPositiveBigInteger(random) + (BigInteger)value) + 1; - } - - private static void VerifyByteExplicitCastFromBigInteger(byte value) - { - BigInteger bigInteger = new BigInteger(value); - VerifyByteExplicitCastFromBigInteger(value, bigInteger); - } - - private static void VerifyByteExplicitCastFromBigInteger(byte value, BigInteger bigInteger) - { - Assert.Equal(value, (byte)bigInteger); - } - - private static void VerifySByteExplicitCastFromBigInteger(sbyte value) - { - BigInteger bigInteger = new BigInteger(value); - VerifySByteExplicitCastFromBigInteger(value, bigInteger); - } - private static void VerifySByteExplicitCastFromBigInteger(sbyte value, BigInteger bigInteger) - { - Assert.Equal(value, (sbyte)bigInteger); - } - - private static void VerifyUInt16ExplicitCastFromBigInteger(ushort value) - { - BigInteger bigInteger = new BigInteger(value); - VerifyUInt16ExplicitCastFromBigInteger(value, bigInteger); - } - private static void VerifyUInt16ExplicitCastFromBigInteger(ushort value, BigInteger bigInteger) - { - Assert.Equal(value, (ushort)bigInteger); - } - - private static void VerifyInt16ExplicitCastFromBigInteger(short value) - { - BigInteger bigInteger = new BigInteger(value); - VerifyInt16ExplicitCastFromBigInteger(value, bigInteger); - } - private static void VerifyInt16ExplicitCastFromBigInteger(short value, BigInteger bigInteger) - { - Assert.Equal(value, (short)bigInteger); - } - - private static void VerifyUInt32ExplicitCastFromBigInteger(uint value) - { - BigInteger bigInteger = new BigInteger(value); - VerifyUInt32ExplicitCastFromBigInteger(value, bigInteger); - } - private static void VerifyUInt32ExplicitCastFromBigInteger(uint value, BigInteger bigInteger) - { - Assert.Equal(value, (uint)bigInteger); - } - - private static void VerifyInt32ExplicitCastFromBigInteger(int value) - { - BigInteger bigInteger = new BigInteger(value); - VerifyInt32ExplicitCastFromBigInteger(value, bigInteger); - } - private static void VerifyInt32ExplicitCastFromBigInteger(int value, BigInteger bigInteger) - { - Assert.Equal(value, (int)bigInteger); - } - - private static void VerifyUInt64ExplicitCastFromBigInteger(ulong value) - { - BigInteger bigInteger = new BigInteger(value); - VerifyUInt64ExplicitCastFromBigInteger(value, bigInteger); - } - private static void VerifyUInt64ExplicitCastFromBigInteger(ulong value, BigInteger bigInteger) - { - Assert.Equal(value, (ulong)bigInteger); - } - - private static void VerifyInt64ExplicitCastFromBigInteger(long value) - { - BigInteger bigInteger = new BigInteger(value); - VerifyInt64ExplicitCastFromBigInteger(value, bigInteger); - } - private static void VerifyInt64ExplicitCastFromBigInteger(long value, BigInteger bigInteger) - { - Assert.Equal(value, (long)bigInteger); - } - - private static void VerifySingleExplicitCastFromBigInteger(float value) - { - BigInteger bigInteger = new BigInteger(value); - VerifySingleExplicitCastFromBigInteger(value, bigInteger); - } - private static void VerifySingleExplicitCastFromBigInteger(float value, BigInteger bigInteger) - { - Assert.Equal((float)Math.Truncate(value), (float)bigInteger); - } - - private static void VerifyDoubleExplicitCastFromBigInteger(double value) - { - BigInteger bigInteger = new BigInteger(value); - VerifyDoubleExplicitCastFromBigInteger(value, bigInteger); - } - private static void VerifyDoubleExplicitCastFromBigInteger(double value, BigInteger bigInteger) - { - Assert.Equal(Math.Truncate(value), (double)bigInteger); - } - - private static void VerifyDecimalExplicitCastFromBigInteger(decimal value) - { - BigInteger bigInteger = new BigInteger(value); - VerifyDecimalExplicitCastFromBigInteger(value, bigInteger); - } - private static void VerifyDecimalExplicitCastFromBigInteger(decimal value, BigInteger bigInteger) - { - Assert.Equal(value, (decimal)bigInteger); - } - - public static byte[] ByteArrayMakeMinSize(byte[] input, int minSize) - { - if (input.Length >= minSize) - { - return input; - } - - byte[] output = new byte[minSize]; - byte filler = 0; - - if ((input[input.Length - 1] & 0x80) != 0) - { - filler = 0xff; - } - - for (int i = 0; i < output.Length; i++) - { - output[i] = (i < input.Length) ? input[i] : filler; - } - - return output; - } } } From 74b4de867fda06d08622239914f6a63238921f89 Mon Sep 17 00:00:00 2001 From: Maksim Golev Date: Wed, 14 Jul 2021 08:17:02 +0400 Subject: [PATCH 02/10] Uncomment of tests according to IEEE 754. (#49611) --- .../tests/BigInteger/cast_from.cs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.Runtime.Numerics/tests/BigInteger/cast_from.cs b/src/libraries/System.Runtime.Numerics/tests/BigInteger/cast_from.cs index 6c30b1606a8ee..ad3f174fa584e 100644 --- a/src/libraries/System.Runtime.Numerics/tests/BigInteger/cast_from.cs +++ b/src/libraries/System.Runtime.Numerics/tests/BigInteger/cast_from.cs @@ -386,10 +386,8 @@ public static IEnumerable RunSingleExplicitCastFromBigIntegerTestSourc { yield return new object[] { new BigInteger(float.MinValue), float.MinValue }; yield return new object[] { new BigInteger(float.MaxValue), float.MaxValue }; -#if false - yield return new object[] { new BigInteger(float.MinValue) - BigInteger.One, float.NegativeInfinity }; - yield return new object[] { new BigInteger(float.MaxValue) + BigInteger.One, float.PositiveInfinity }; -#endif + yield return new object[] { new BigInteger(float.MinValue) - BigInteger.One, float.MinValue }; + yield return new object[] { new BigInteger(float.MaxValue) + BigInteger.One, float.MaxValue }; yield return new object[] { new BigInteger(-1f), -1f }; yield return new object[] { new BigInteger(0f), 0f }; yield return new object[] { new BigInteger(1f), 1f }; @@ -423,10 +421,8 @@ public static IEnumerable RunDoubleExplicitCastFromBigIntegerTestSourc { yield return new object[] { new BigInteger(double.MinValue), double.MinValue }; yield return new object[] { new BigInteger(double.MaxValue), double.MaxValue }; -#if false - yield return new object[] { new BigInteger(double.MinValue) - BigInteger.One, double.NegativeInfinity }; - yield return new object[] { new BigInteger(double.MaxValue) + BigInteger.One, double.PositiveInfinity }; -#endif + yield return new object[] { new BigInteger(double.MinValue) - BigInteger.One, double.MinValue }; + yield return new object[] { new BigInteger(double.MaxValue) + BigInteger.One, double.MaxValue }; yield return new object[] { new BigInteger(-1.0), -1.0 }; yield return new object[] { new BigInteger(0.0), 0.0 }; yield return new object[] { new BigInteger(1.0), 1.0 }; From d170dbb7757a29a3eb20a4d76fc174ed7c61a231 Mon Sep 17 00:00:00 2001 From: Maksim Golev Date: Wed, 14 Jul 2021 12:42:40 +0400 Subject: [PATCH 03/10] Switching to TheoryAttribute for testing converting from BigInteger. (#49611) --- .../tests/BigInteger/cast_to.cs | 993 ++++++------------ 1 file changed, 320 insertions(+), 673 deletions(-) diff --git a/src/libraries/System.Runtime.Numerics/tests/BigInteger/cast_to.cs b/src/libraries/System.Runtime.Numerics/tests/BigInteger/cast_to.cs index 6a6cb98e52101..7647d380e4ca5 100644 --- a/src/libraries/System.Runtime.Numerics/tests/BigInteger/cast_to.cs +++ b/src/libraries/System.Runtime.Numerics/tests/BigInteger/cast_to.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; +using System.Collections.Generic; using Xunit; namespace System.Numerics.Tests @@ -13,792 +13,439 @@ public class cast_toTest private const int NumberOfRandomIterations = 10; private static Random s_random = new Random(100); - [Fact] - public static void RunByteImplicitCastToBigIntegerTests() + public static IEnumerable RunByteImplicitCastToBigIntegerTestSources { - // Byte Implicit Cast to BigInteger: Byte.MinValue - VerifyByteImplicitCastToBigInteger(byte.MinValue); - - // Byte Implicit Cast to BigInteger: 0 - VerifyByteImplicitCastToBigInteger(0); - - // Byte Implicit Cast to BigInteger: 1 - VerifyByteImplicitCastToBigInteger(1); - - // Byte Implicit Cast to BigInteger: Random Positive - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifyByteImplicitCastToBigInteger((byte)s_random.Next(1, byte.MaxValue)); + get + { + yield return new object[] { byte.MinValue, new BigInteger(byte.MinValue) }; + yield return new object[] { byte.MaxValue, new BigInteger(byte.MaxValue) }; + yield return new object[] { 0, new BigInteger(0) }; + yield return new object[] { 1, new BigInteger(1) }; + for (int i = 0; i < NumberOfRandomIterations; i++) + { + byte currentValue = (byte)s_random.Next(byte.MinValue, byte.MaxValue); + yield return new object[] { currentValue, new BigInteger(currentValue) }; + } } - - // Byte Implicit Cast to BigInteger: Byte.MaxValue - VerifyByteImplicitCastToBigInteger(byte.MaxValue); } - [Fact] - public static void RunSByteImplicitCastToBigIntegerTests() + [Theory] + [MemberData(nameof(RunByteImplicitCastToBigIntegerTestSources))] + public void RunByteImplicitCastToBigIntegerTest(byte testValue, BigInteger expectedValue) { - // SByte Implicit Cast to BigInteger: SByte.MinValue - VerifySByteImplicitCastToBigInteger(sbyte.MinValue); - - // SByte Implicit Cast to BigInteger: Random Negative - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifySByteImplicitCastToBigInteger((sbyte)s_random.Next(sbyte.MinValue, 0)); - } + BigInteger actualValue; - // SByte Implicit Cast to BigInteger: -1 - VerifySByteImplicitCastToBigInteger(-1); + actualValue = testValue; - // SByte Implicit Cast to BigInteger: 0 - VerifySByteImplicitCastToBigInteger(0); - - // SByte Implicit Cast to BigInteger: 1 - VerifySByteImplicitCastToBigInteger(1); - - // SByte Implicit Cast to BigInteger: Random Positive - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifySByteImplicitCastToBigInteger((sbyte)s_random.Next(1, sbyte.MaxValue)); - } - - // SByte Implicit Cast to BigInteger: SByte.MaxValue - VerifySByteImplicitCastToBigInteger(sbyte.MaxValue); + Assert.Equal(expectedValue, actualValue); } - [Fact] - public static void RunUInt16ImplicitCastToBigIntegerTests() + public static IEnumerable RunSByteImplicitCastToBigIntegerTestSources { - // UInt16 Implicit Cast to BigInteger: UInt16.MinValue - VerifyUInt16ImplicitCastToBigInteger(ushort.MinValue); - - // UInt16 Implicit Cast to BigInteger: 0 - VerifyUInt16ImplicitCastToBigInteger(0); - - // UInt16 Implicit Cast to BigInteger: 1 - VerifyUInt16ImplicitCastToBigInteger(1); - - // UInt16 Implicit Cast to BigInteger: Random Positive - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifyUInt16ImplicitCastToBigInteger((ushort)s_random.Next(1, ushort.MaxValue)); + get + { + yield return new object[] { sbyte.MinValue, new BigInteger(sbyte.MinValue) }; + yield return new object[] { sbyte.MaxValue, new BigInteger(sbyte.MaxValue) }; + yield return new object[] { -1, new BigInteger(-1) }; + yield return new object[] { 0, new BigInteger(0) }; + yield return new object[] { 1, new BigInteger(1) }; + for (int i = 0; i < NumberOfRandomIterations; i++) + { + sbyte currentValue = (sbyte)s_random.Next(sbyte.MinValue, 0); + yield return new object[] { currentValue, new BigInteger(currentValue) }; + } + for (int i = 0; i < NumberOfRandomIterations; i++) + { + sbyte currentValue = (sbyte)s_random.Next(0, sbyte.MaxValue); + yield return new object[] { currentValue, new BigInteger(currentValue) }; + } } - - // UInt16 Implicit Cast to BigInteger: UInt16.MaxValue - VerifyUInt16ImplicitCastToBigInteger(ushort.MaxValue); } - [Fact] - public static void RunInt16ImplicitCastToBigIntegerTests() + [Theory] + [MemberData(nameof(RunSByteImplicitCastToBigIntegerTestSources))] + public void RunSByteImplicitCastToBigIntegerTest(sbyte testValue, BigInteger expectedValue) { - // Int16 Implicit Cast to BigInteger: Int16.MinValue - VerifyInt16ImplicitCastToBigInteger(short.MinValue); - - // Int16 Implicit Cast to BigInteger: Random Negative - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifyInt16ImplicitCastToBigInteger((short)s_random.Next(short.MinValue, 0)); - } - - // Int16 Implicit Cast to BigInteger: -1 - VerifyInt16ImplicitCastToBigInteger(-1); + BigInteger actualValue; - // Int16 Implicit Cast to BigInteger: 0 - VerifyInt16ImplicitCastToBigInteger(0); + actualValue = testValue; - // Int16 Implicit Cast to BigInteger: 1 - VerifyInt16ImplicitCastToBigInteger(1); - - // Int16 Implicit Cast to BigInteger: Random Positive - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifyInt16ImplicitCastToBigInteger((short)s_random.Next(1, short.MaxValue)); - } - - // Int16 Implicit Cast to BigInteger: Int16.MaxValue - VerifyInt16ImplicitCastToBigInteger(short.MaxValue); + Assert.Equal(expectedValue, actualValue); } - [Fact] - public static void RunUInt32ImplicitCastToBigIntegerTests() + public static IEnumerable RunUInt16ImplicitCastToBigIntegerTestSources { - // UInt32 Implicit Cast to BigInteger: UInt32.MinValue - VerifyUInt32ImplicitCastToBigInteger(uint.MinValue); - - // UInt32 Implicit Cast to BigInteger: 0 - VerifyUInt32ImplicitCastToBigInteger(0); - - // UInt32 Implicit Cast to BigInteger: 1 - VerifyUInt32ImplicitCastToBigInteger(1); - - // UInt32 Implicit Cast to BigInteger: Random Positive - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifyUInt32ImplicitCastToBigInteger((uint)(uint.MaxValue * s_random.NextDouble())); + get + { + yield return new object[] { ushort.MinValue, new BigInteger(ushort.MinValue) }; + yield return new object[] { ushort.MaxValue, new BigInteger(ushort.MaxValue) }; + yield return new object[] { 0, new BigInteger(0) }; + yield return new object[] { 1, new BigInteger(1) }; + for (int i = 0; i < NumberOfRandomIterations; i++) + { + ushort currentValue = (ushort)s_random.Next(ushort.MinValue, ushort.MaxValue); + yield return new object[] { currentValue, new BigInteger(currentValue) }; + } } - - // UInt32 Implicit Cast to BigInteger: UInt32.MaxValue - VerifyUInt32ImplicitCastToBigInteger(uint.MaxValue); } - [Fact] - public static void RunInt32ImplicitCastToBigIntegerTests() + [Theory] + [MemberData(nameof(RunUInt16ImplicitCastToBigIntegerTestSources))] + public void RunUInt16ImplicitCastToBigIntegerTest(ushort testValue, BigInteger expectedValue) { - // Int32 Implicit Cast to BigInteger: Int32.MinValue - VerifyInt32ImplicitCastToBigInteger(int.MinValue); + BigInteger actualValue; - // Int32 Implicit Cast to BigInteger: Random Negative - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifyInt32ImplicitCastToBigInteger((int)s_random.Next(int.MinValue, 0)); - } - - // Int32 Implicit Cast to BigInteger: -1 - VerifyInt32ImplicitCastToBigInteger(-1); - - // Int32 Implicit Cast to BigInteger: 0 - VerifyInt32ImplicitCastToBigInteger(0); - - // Int32 Implicit Cast to BigInteger: 1 - VerifyInt32ImplicitCastToBigInteger(1); - - // Int32 Implicit Cast to BigInteger: Random Positive - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifyInt32ImplicitCastToBigInteger((int)s_random.Next(1, int.MaxValue)); - } + actualValue = testValue; - // Int32 Implicit Cast to BigInteger: Int32.MaxValue - VerifyInt32ImplicitCastToBigInteger(int.MaxValue); + Assert.Equal(expectedValue, actualValue); } - [Fact] - public static void RunUInt64ImplicitCastToBigIntegerTests() + public static IEnumerable RunInt16ImplicitCastToBigIntegerTestSources { - // UInt64 Implicit Cast to BigInteger: UInt64.MinValue - VerifyUInt64ImplicitCastToBigInteger(ulong.MinValue); - - // UInt64 Implicit Cast to BigInteger: 0 - VerifyUInt64ImplicitCastToBigInteger(0); - - // UInt64 Implicit Cast to BigInteger: 1 - VerifyUInt64ImplicitCastToBigInteger(1); - - // UInt64 Implicit Cast to BigInteger: Random Positive - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifyUInt64ImplicitCastToBigInteger((ulong)(ulong.MaxValue * s_random.NextDouble())); + get + { + yield return new object[] { short.MinValue, new BigInteger(short.MinValue) }; + yield return new object[] { short.MaxValue, new BigInteger(short.MaxValue) }; + yield return new object[] { -1, new BigInteger(-1) }; + yield return new object[] { 0, new BigInteger(0) }; + yield return new object[] { 1, new BigInteger(1) }; + for (int i = 0; i < NumberOfRandomIterations; i++) + { + short currentValue = (short)s_random.Next(short.MinValue, 0); + yield return new object[] { currentValue, new BigInteger(currentValue) }; + } + for (int i = 0; i < NumberOfRandomIterations; i++) + { + short currentValue = (short)s_random.Next(0, short.MaxValue); + yield return new object[] { currentValue, new BigInteger(currentValue) }; + } } - - // UInt64 Implicit Cast to BigInteger: UInt64.MaxValue - VerifyUInt64ImplicitCastToBigInteger(ulong.MaxValue); } - [Fact] - public static void RunInt64ImplicitCastToBigIntegerTests() + [Theory] + [MemberData(nameof(RunInt16ImplicitCastToBigIntegerTestSources))] + public void RunInt16ImplicitCastToBigIntegerTest(short testValue, BigInteger expectedValue) { - // Int64 Implicit Cast to BigInteger: Int64.MinValue - VerifyInt64ImplicitCastToBigInteger(long.MinValue); - - // Int64 Implicit Cast to BigInteger: Random Negative - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifyInt64ImplicitCastToBigInteger(((long)(long.MaxValue * s_random.NextDouble())) - long.MaxValue); - } - - // Int64 Implicit Cast to BigInteger: -1 - VerifyInt64ImplicitCastToBigInteger(-1); - - // Int64 Implicit Cast to BigInteger: 0 - VerifyInt64ImplicitCastToBigInteger(0); - - // Int64 Implicit Cast to BigInteger: 1 - VerifyInt64ImplicitCastToBigInteger(1); + BigInteger actualValue; - // Int64 Implicit Cast to BigInteger: Random Positive - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifyInt64ImplicitCastToBigInteger((long)(long.MaxValue * s_random.NextDouble())); - } + actualValue = testValue; - // Int64 Implicit Cast to BigInteger: Int64.MaxValue - VerifyInt64ImplicitCastToBigInteger(long.MaxValue); + Assert.Equal(expectedValue, actualValue); } - [Fact] - public static void RunSingleExplicitCastToBigIntegerTests() + public static IEnumerable RunUInt32ImplicitCastToBigIntegerTestSources { - float value; - - // Single Explicit Cast to BigInteger: Single.NegativeInfinity - Assert.Throws(() => { BigInteger temp = (BigInteger)float.NegativeInfinity; }); - - // Single Explicit Cast to BigInteger: Single.MinValue - VerifySingleExplicitCastToBigInteger(float.MinValue); - - // Single Explicit Cast to BigInteger: Random Negative - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifySingleExplicitCastToBigInteger(((float)(float.MaxValue * s_random.NextDouble())) - float.MaxValue); + get + { + yield return new object[] { uint.MinValue, new BigInteger(uint.MinValue) }; + yield return new object[] { uint.MaxValue, new BigInteger(uint.MaxValue) }; + yield return new object[] { 0, new BigInteger(0) }; + yield return new object[] { 1, new BigInteger(1) }; + for (int i = 0; i < NumberOfRandomIterations; i++) + { + uint currentValue = (uint)(uint.MaxValue * s_random.NextDouble()); + yield return new object[] { currentValue, new BigInteger(currentValue) }; + } } - - // Single Explicit Cast to BigInteger: Random Non-Integral Negative > -100 - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifySingleExplicitCastToBigInteger((float)(-100 * s_random.NextDouble())); - } - - // Single Explicit Cast to BigInteger: -1 - VerifySingleExplicitCastToBigInteger(-1); - - // Single Explicit Cast to BigInteger: 0 - VerifySingleExplicitCastToBigInteger(0); - - // Single Explicit Cast to BigInteger: 1 - VerifySingleExplicitCastToBigInteger(1); - - // Single Explicit Cast to BigInteger: Random Non-Integral Positive < 100 - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifySingleExplicitCastToBigInteger((float)(100 * s_random.NextDouble())); - } - - // Single Explicit Cast to BigInteger: Random Positive - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifySingleExplicitCastToBigInteger((float)(float.MaxValue * s_random.NextDouble())); - } - - // Single Explicit Cast to BigInteger: Single.MaxValue - VerifySingleExplicitCastToBigInteger(float.MaxValue); - - // Single Explicit Cast to BigInteger: Single.PositiveInfinity - Assert.Throws(() => { BigInteger temp = (BigInteger)float.PositiveInfinity; }); - - // double.IsInfinity(float.MaxValue * 2.0f) == false, but we don't want this odd behavior here - Assert.Throws(() => { BigInteger temp = (BigInteger)(float.MaxValue * 2.0f); }); - - // Single Explicit Cast to BigInteger: Single.Epsilon - VerifySingleExplicitCastToBigInteger(float.Epsilon); - - // Single Explicit Cast to BigInteger: Single.NaN - Assert.Throws(() => { BigInteger temp = (BigInteger)float.NaN; }); - - //There are multiple ways to represent a NaN just try another one - // Single Explicit Cast to BigInteger: Single.NaN 2 - Assert.Throws(() => { BigInteger temp = (BigInteger)ConvertInt32ToSingle(0x7FC00000); }); - - // Single Explicit Cast to BigInteger: Smallest Exponent - VerifySingleExplicitCastToBigInteger((float)Math.Pow(2, -126)); - - // Single Explicit Cast to BigInteger: Largest Exponent - VerifySingleExplicitCastToBigInteger((float)Math.Pow(2, 127)); - - // Single Explicit Cast to BigInteger: Largest number less then 1 - value = 0; - for (int i = 1; i <= 24; ++i) - { - value += (float)(Math.Pow(2, -i)); - } - VerifySingleExplicitCastToBigInteger(value); - - // Single Explicit Cast to BigInteger: Smallest number greater then 1 - value = (float)(1 + Math.Pow(2, -23)); - VerifySingleExplicitCastToBigInteger(value); - - // Single Explicit Cast to BigInteger: Largest number less then 2 - value = 0; - for (int i = 1; i <= 23; ++i) - { - value += (float)(Math.Pow(2, -i)); - } - value += 1; - VerifySingleExplicitCastToBigInteger(value); } - [Fact] - public static void RunDoubleExplicitCastToBigIntegerTests() + [Theory] + [MemberData(nameof(RunUInt32ImplicitCastToBigIntegerTestSources))] + public void RunUInt32ImplicitCastToBigIntegerTest(uint testValue, BigInteger expectedValue) { - double value; - - // Double Explicit Cast to BigInteger: Double.NegativeInfinity - Assert.Throws(() => { BigInteger temp = (BigInteger)double.NegativeInfinity; }); - - // Double Explicit Cast to BigInteger: Double.MinValue - VerifyDoubleExplicitCastToBigInteger(double.MinValue); - - // Double Explicit Cast to BigInteger: Random Negative - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifyDoubleExplicitCastToBigInteger(((double)(double.MaxValue * s_random.NextDouble())) - double.MaxValue); - } - - // Double Explicit Cast to BigInteger: Random Non-Integral Negative > -100 - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifyDoubleExplicitCastToBigInteger((double)(-100 * s_random.NextDouble())); - } + BigInteger actualValue; - // Double Explicit Cast to BigInteger: -1 - VerifyDoubleExplicitCastToBigInteger(-1); + actualValue = testValue; - // Double Explicit Cast to BigInteger: 0 - VerifyDoubleExplicitCastToBigInteger(0); - - // Double Explicit Cast to BigInteger: 1 - VerifyDoubleExplicitCastToBigInteger(1); - - // Double Explicit Cast to BigInteger: Random Non-Integral Positive < 100 - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifyDoubleExplicitCastToBigInteger((double)(100 * s_random.NextDouble())); - } - - // Double Explicit Cast to BigInteger: Random Positive - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - VerifyDoubleExplicitCastToBigInteger((double)(double.MaxValue * s_random.NextDouble())); - } - - // Double Explicit Cast to BigInteger: Double.MaxValue - VerifyDoubleExplicitCastToBigInteger(double.MaxValue); - - // Double Explicit Cast to BigInteger: Double.PositiveInfinity - Assert.Throws(() => { BigInteger temp = (BigInteger)double.PositiveInfinity; }); - - // Double Explicit Cast to BigInteger: Double.Epsilon - VerifyDoubleExplicitCastToBigInteger(double.Epsilon); - - // Double Explicit Cast to BigInteger: Double.NaN - Assert.Throws(() => { BigInteger temp = (BigInteger)double.NaN; }); - - //There are multiple ways to represent a NaN just try another one - // Double Explicit Cast to BigInteger: Double.NaN 2 - Assert.Throws(() => { BigInteger temp = (BigInteger)ConvertInt64ToDouble(0x7FF8000000000000); }); - - // Double Explicit Cast to BigInteger: Smallest Exponent - VerifyDoubleExplicitCastToBigInteger((double)Math.Pow(2, -1022)); - - // Double Explicit Cast to BigInteger: Largest Exponent - VerifyDoubleExplicitCastToBigInteger((double)Math.Pow(2, 1023)); - - // Double Explicit Cast to BigInteger: Largest number less then 1 - value = 0; - for (int i = 1; i <= 53; ++i) - { - value += (double)(Math.Pow(2, -i)); - } - VerifyDoubleExplicitCastToBigInteger(value); - - // Double Explicit Cast to BigInteger: Smallest number greater then 1 - value = (double)(1 + Math.Pow(2, -52)); - VerifyDoubleExplicitCastToBigInteger(value); - - // Double Explicit Cast to BigInteger: Largest number less then 2 - value = 0; - for (int i = 1; i <= 52; ++i) - { - value += (double)(Math.Pow(2, -i)); - } - value += 1; - VerifyDoubleExplicitCastToBigInteger(value); + Assert.Equal(expectedValue, actualValue); } - [Fact] - public static void RunDecimalExplicitCastToBigIntegerTests() + public static IEnumerable RunInt32ImplicitCastToBigIntegerTestSources { - decimal value; - - // Decimal Explicit Cast to BigInteger: Decimal.MinValue - VerifyDecimalExplicitCastToBigInteger(decimal.MinValue); - - // Decimal Explicit Cast to BigInteger: Random Negative - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - value = new decimal( - s_random.Next(int.MinValue, int.MaxValue), - s_random.Next(int.MinValue, int.MaxValue), - s_random.Next(int.MinValue, int.MaxValue), - true, - (byte)s_random.Next(0, 29)); - VerifyDecimalExplicitCastToBigInteger(value); - } - - // Decimal Explicit Cast to BigInteger: -1 - VerifyDecimalExplicitCastToBigInteger(-1); - - // Decimal Explicit Cast to BigInteger: 0 - VerifyDecimalExplicitCastToBigInteger(0); - - // Decimal Explicit Cast to BigInteger: 1 - VerifyDecimalExplicitCastToBigInteger(1); - - // Decimal Explicit Cast to BigInteger: Random Positive - for (int i = 0; i < NumberOfRandomIterations; ++i) - { - value = new decimal( - s_random.Next(int.MinValue, int.MaxValue), - s_random.Next(int.MinValue, int.MaxValue), - s_random.Next(int.MinValue, int.MaxValue), - false, - (byte)s_random.Next(0, 29)); - VerifyDecimalExplicitCastToBigInteger(value); + get + { + yield return new object[] { int.MinValue, new BigInteger(int.MinValue) }; + yield return new object[] { int.MaxValue, new BigInteger(int.MaxValue) }; + yield return new object[] { -1, new BigInteger(-1) }; + yield return new object[] { 0, new BigInteger(0) }; + yield return new object[] { 1, new BigInteger(1) }; + for (int i = 0; i < NumberOfRandomIterations; i++) + { + int currentValue = s_random.Next(int.MinValue, 0); + yield return new object[] { currentValue, new BigInteger(currentValue) }; + } + for (int i = 0; i < NumberOfRandomIterations; i++) + { + int currentValue = s_random.Next(0, int.MaxValue); + yield return new object[] { currentValue, new BigInteger(currentValue) }; + } } - - // Decimal Explicit Cast to BigInteger: Decimal.MaxValue - VerifyDecimalExplicitCastToBigInteger(decimal.MaxValue); - - // Decimal Explicit Cast to BigInteger: Smallest Exponent - unchecked - { - value = new decimal(1, 0, 0, false, 0); - } - VerifyDecimalExplicitCastToBigInteger(value); - - // Decimal Explicit Cast to BigInteger: Largest Exponent and zero integer - unchecked - { - value = new decimal(0, 0, 0, false, 28); - } - VerifyDecimalExplicitCastToBigInteger(value); - - // Decimal Explicit Cast to BigInteger: Largest Exponent and non zero integer - unchecked - { - value = new decimal(1, 0, 0, false, 28); - } - VerifyDecimalExplicitCastToBigInteger(value); - - // Decimal Explicit Cast to BigInteger: Largest number less then 1 - value = 1 - new decimal(1, 0, 0, false, 28); - VerifyDecimalExplicitCastToBigInteger(value); - - // Decimal Explicit Cast to BigInteger: Smallest number greater then 1 - value = 1 + new decimal(1, 0, 0, false, 28); - VerifyDecimalExplicitCastToBigInteger(value); - - // Decimal Explicit Cast to BigInteger: Largest number less then 2 - value = 2 - new decimal(1, 0, 0, false, 28); - VerifyDecimalExplicitCastToBigInteger(value); } - private static float ConvertInt32ToSingle(int value) + [Theory] + [MemberData(nameof(RunInt32ImplicitCastToBigIntegerTestSources))] + public void RunInt32ImplicitCastToBigIntegerTest(int testValue, BigInteger expectedValue) { - return BitConverter.ToSingle(BitConverter.GetBytes(value), 0); - } + BigInteger actualValue; - private static double ConvertInt64ToDouble(long value) - { - return BitConverter.ToDouble(BitConverter.GetBytes(value), 0); + actualValue = testValue; + + Assert.Equal(expectedValue, actualValue); } - private static void VerifyByteImplicitCastToBigInteger(byte value) + public static IEnumerable RunUInt64ImplicitCastToBigIntegerTestSources { - BigInteger bigInteger = value; - - Assert.Equal(value, bigInteger); - Assert.Equal(value.ToString(), bigInteger.ToString()); - Assert.Equal(value, (byte)bigInteger); - - if (value != byte.MaxValue) - { - Assert.Equal((byte)(value + 1), (byte)(bigInteger + 1)); + get + { + yield return new object[] { ulong.MinValue, new BigInteger(ulong.MinValue) }; + yield return new object[] { ulong.MaxValue, new BigInteger(ulong.MaxValue) }; + yield return new object[] { 0, new BigInteger(0) }; + yield return new object[] { 1, new BigInteger(1) }; + for (int i = 0; i < NumberOfRandomIterations; i++) + { + ulong currentValue = (ulong)(ulong.MaxValue * s_random.NextDouble()); + yield return new object[] { currentValue, new BigInteger(currentValue) }; + } } - - if (value != byte.MinValue) - { - Assert.Equal((byte)(value - 1), (byte)(bigInteger - 1)); - } - - VerifyBigIntegerUsingIdentities(bigInteger, 0 == value); } - private static void VerifySByteImplicitCastToBigInteger(sbyte value) + [Theory] + [MemberData(nameof(RunUInt64ImplicitCastToBigIntegerTestSources))] + public void RunUInt64ImplicitCastToBigIntegerTest(ulong testValue, BigInteger expectedValue) { - BigInteger bigInteger = value; + BigInteger actualValue; - Assert.Equal(value, bigInteger); - Assert.Equal(value.ToString(), bigInteger.ToString()); - Assert.Equal(value, (sbyte)bigInteger); + actualValue = testValue; - if (value != sbyte.MaxValue) - { - Assert.Equal((sbyte)(value + 1), (sbyte)(bigInteger + 1)); - } - - if (value != sbyte.MinValue) - { - Assert.Equal((sbyte)(value - 1), (sbyte)(bigInteger - 1)); - } - - VerifyBigIntegerUsingIdentities(bigInteger, 0 == value); + Assert.Equal(expectedValue, actualValue); } - private static void VerifyUInt16ImplicitCastToBigInteger(ushort value) + public static IEnumerable RunInt64ImplicitCastToBigIntegerTestSources { - BigInteger bigInteger = value; - - Assert.Equal(value, bigInteger); - Assert.Equal(value.ToString(), bigInteger.ToString()); - Assert.Equal(value, (ushort)bigInteger); - - if (value != ushort.MaxValue) - { - Assert.Equal((ushort)(value + 1), (ushort)(bigInteger + 1)); + get + { + yield return new object[] { long.MinValue, new BigInteger(long.MinValue) }; + yield return new object[] { long.MaxValue, new BigInteger(long.MaxValue) }; + yield return new object[] { -1, new BigInteger(-1) }; + yield return new object[] { 0, new BigInteger(0) }; + yield return new object[] { 1, new BigInteger(1) }; + for (int i = 0; i < NumberOfRandomIterations; i++) + { + long currentValue = (long)(long.MinValue * s_random.NextDouble()); + yield return new object[] { currentValue, new BigInteger(currentValue) }; + } + for (int i = 0; i < NumberOfRandomIterations; i++) + { + long currentValue = (long)(long.MaxValue * s_random.NextDouble()); + yield return new object[] { currentValue, new BigInteger(currentValue) }; + } } - - if (value != ushort.MinValue) - { - Assert.Equal((ushort)(value - 1), (ushort)(bigInteger - 1)); - } - - VerifyBigIntegerUsingIdentities(bigInteger, 0 == value); } - private static void VerifyInt16ImplicitCastToBigInteger(short value) + [Theory] + [MemberData(nameof(RunInt64ImplicitCastToBigIntegerTestSources))] + public void RunInt64ImplicitCastToBigIntegerTest(long testValue, BigInteger expectedValue) { - BigInteger bigInteger = value; + BigInteger actualValue; - Assert.Equal(value, bigInteger); - Assert.Equal(value.ToString(), bigInteger.ToString()); - Assert.Equal(value, (short)bigInteger); + actualValue = testValue; - if (value != short.MaxValue) - { - Assert.Equal((short)(value + 1), (short)(bigInteger + 1)); - } - - if (value != short.MinValue) - { - Assert.Equal((short)(value - 1), (short)(bigInteger - 1)); - } - - VerifyBigIntegerUsingIdentities(bigInteger, 0 == value); + Assert.Equal(expectedValue, actualValue); } - private static void VerifyUInt32ImplicitCastToBigInteger(uint value) + public static IEnumerable RunSingleExplicitCastToBigIntegerThrowsOverflowExceptionTestSources { - BigInteger bigInteger = value; - - Assert.Equal(value, bigInteger); - Assert.Equal(value.ToString(), bigInteger.ToString()); - Assert.Equal(value, (uint)bigInteger); - - if (value != uint.MaxValue) - { - Assert.Equal((uint)(value + 1), (uint)(bigInteger + 1)); - } - - if (value != uint.MinValue) + get { - Assert.Equal((uint)(value - 1), (uint)(bigInteger - 1)); + yield return new object[] { float.NaN }; + yield return new object[] { float.NegativeInfinity }; + yield return new object[] { float.PositiveInfinity }; + yield return new object[] { float.MaxValue * 2.0f }; } - - VerifyBigIntegerUsingIdentities(bigInteger, 0 == value); } - private static void VerifyInt32ImplicitCastToBigInteger(int value) + [Theory] + [MemberData(nameof(RunSingleExplicitCastToBigIntegerThrowsOverflowExceptionTestSources))] + public void RunSingleExplicitCastToBigIntegerThrowsOverflowExceptionTest(float testValue) { - BigInteger bigInteger = value; - - Assert.Equal(value, bigInteger); - Assert.Equal(value.ToString(), bigInteger.ToString()); - Assert.Equal(value, (int)bigInteger); - - if (value != int.MaxValue) - { - Assert.Equal((int)(value + 1), (int)(bigInteger + 1)); - } - - if (value != int.MinValue) - { - Assert.Equal((int)(value - 1), (int)(bigInteger - 1)); - } - - VerifyBigIntegerUsingIdentities(bigInteger, 0 == value); + Assert.Throws(() => (BigInteger)testValue); } - private static void VerifyUInt64ImplicitCastToBigInteger(ulong value) + public static IEnumerable RunSingleImplicitCastToBigIntegerTestSources { - BigInteger bigInteger = value; - - Assert.Equal(value, bigInteger); - Assert.Equal(value.ToString(), bigInteger.ToString()); - Assert.Equal(value, (ulong)bigInteger); - - if (value != ulong.MaxValue) - { - Assert.Equal((ulong)(value + 1), (ulong)(bigInteger + 1)); - } - - if (value != ulong.MinValue) - { - Assert.Equal((ulong)(value - 1), (ulong)(bigInteger - 1)); + get + { + yield return new object[] { float.MinValue, new BigInteger(float.MinValue) }; + yield return new object[] { float.Epsilon, new BigInteger(float.Epsilon) }; + yield return new object[] { float.MaxValue, new BigInteger(float.MaxValue) }; + yield return new object[] { -1, new BigInteger(-1) }; + yield return new object[] { 0, new BigInteger(0) }; + yield return new object[] { Math.Pow(2, -126), new BigInteger(Math.Pow(2, -126)) }; + yield return new object[] { 1 + Math.Pow(2, -23), new BigInteger(1 + Math.Pow(2, -23)) }; + yield return new object[] { 1, new BigInteger(1) }; + yield return new object[] { Math.Pow(2, 127), new BigInteger(Math.Pow(2, 127)) }; + float value = 0; + for (int i = 1; i <= 24; ++i) + { + value += (float)(Math.Pow(2, -i)); + } + yield return new object[] { value, new BigInteger(value) }; + value = 0; + for (int i = 1; i <= 23; ++i) + { + value += (float)(Math.Pow(2, -i)); + } + for (int i = 0; i < NumberOfRandomIterations; i++) + { + float currentValue = (float)(float.MinValue * s_random.NextDouble()); + yield return new object[] { currentValue, new BigInteger(currentValue) }; + } + for (int i = 0; i < NumberOfRandomIterations; i++) + { + float currentValue = (float)(float.MaxValue * s_random.NextDouble()); + yield return new object[] { currentValue, new BigInteger(currentValue) }; + } } - - VerifyBigIntegerUsingIdentities(bigInteger, 0 == value); } - private static void VerifyInt64ImplicitCastToBigInteger(long value) + [Theory] + [MemberData(nameof(RunSingleImplicitCastToBigIntegerTestSources))] + public static void RunSingleExplicitCastToBigIntegerTest(float testValue, BigInteger expectedValue) { - BigInteger bigInteger = value; - - Assert.Equal(value, bigInteger); - Assert.Equal(value.ToString(), bigInteger.ToString()); - Assert.Equal(value, (long)bigInteger); + BigInteger actualValue; - if (value != long.MaxValue) - { - Assert.Equal((long)(value + 1), (long)(bigInteger + 1)); - } + actualValue = (BigInteger)testValue; - if (value != long.MinValue) - { - Assert.Equal((long)(value - 1), (long)(bigInteger - 1)); - } - - VerifyBigIntegerUsingIdentities(bigInteger, 0 == value); + Assert.Equal(expectedValue, actualValue); } - private static void VerifySingleExplicitCastToBigInteger(float value) + public static IEnumerable RunDoubleExplicitCastToBigIntegerThrowsOverflowExceptionTestSources { - float expectedValue; - BigInteger bigInteger; - - if (value < 0) - { - expectedValue = (float)Math.Ceiling(value); - } - else - { - expectedValue = (float)Math.Floor(value); - } - - bigInteger = (BigInteger)value; - - Assert.Equal(expectedValue, (float)bigInteger); - - // Single can only accurately represent integers between -16777216 and 16777216 exclusive. - // ToString starts to become inaccurate at this point. - if (expectedValue < 16777216 && -16777216 < expectedValue) + get { - Assert.Equal(expectedValue.ToString("G9"), bigInteger.ToString()); + yield return new object[] { double.NaN }; + yield return new object[] { double.NegativeInfinity }; + yield return new object[] { double.PositiveInfinity }; } - - if (expectedValue != Math.Floor(float.MaxValue)) - { - Assert.Equal((float)(expectedValue + 1), (float)(bigInteger + 1)); - } - - if (expectedValue != Math.Ceiling(float.MinValue)) - { - Assert.Equal((float)(expectedValue - 1), (float)(bigInteger - 1)); - } - - VerifyBigIntegerUsingIdentities(bigInteger, 0 == expectedValue); } - private static void VerifyDoubleExplicitCastToBigInteger(double value) + [Theory] + [MemberData(nameof(RunDoubleExplicitCastToBigIntegerThrowsOverflowExceptionTestSources))] + public void RunDoubleExplicitCastToBigIntegerThrowsOverflowExceptionTest(double testValue) { - double expectedValue; - BigInteger bigInteger; + Assert.Throws(() => (BigInteger)testValue); + } - if (value < 0) - { - expectedValue = Math.Ceiling(value); - } - else - { - expectedValue = Math.Floor(value); + public static IEnumerable RunDoubleImplicitCastToBigIntegerTestSources + { + get + { + yield return new object[] { double.MinValue, new BigInteger(double.MinValue) }; + yield return new object[] { double.Epsilon, new BigInteger(double.Epsilon) }; + yield return new object[] { double.MaxValue, new BigInteger(double.MaxValue) }; + yield return new object[] { -1, new BigInteger(-1) }; + yield return new object[] { 0, new BigInteger(0) }; + yield return new object[] { Math.Pow(2, -1022), new BigInteger(Math.Pow(2, -1022)) }; + yield return new object[] { 1 + Math.Pow(2, -52), new BigInteger(1 + Math.Pow(2, -52)) }; + yield return new object[] { 1, new BigInteger(1) }; + yield return new object[] { Math.Pow(2, 1023), new BigInteger(Math.Pow(2, 1023)) }; + double value = 0; + for (int i = 1; i <= 53; ++i) + { + value += Math.Pow(2, -i); + } + yield return new object[] { value, new BigInteger(value) }; + value = 0; + for (int i = 1; i <= 52; ++i) + { + value += Math.Pow(2, -i); + } + yield return new object[] { value, new BigInteger(value) }; + for (int i = 0; i < NumberOfRandomIterations; i++) + { + double currentValue = double.MinValue * s_random.NextDouble(); + yield return new object[] { currentValue, new BigInteger(currentValue) }; + } + for (int i = 0; i < NumberOfRandomIterations; i++) + { + double currentValue = double.MaxValue * s_random.NextDouble(); + yield return new object[] { currentValue, new BigInteger(currentValue) }; + } } + } - bigInteger = (BigInteger)value; - - Assert.Equal(expectedValue, (double)bigInteger); + [Theory] + [MemberData(nameof(RunDoubleImplicitCastToBigIntegerTestSources))] + public static void RunDoubleExplicitCastToBigIntegerTests(double testValue, BigInteger expectedValue) + { + BigInteger actualValue; - // Double can only accurately represent integers between -9007199254740992 and 9007199254740992 exclusive. - // ToString starts to become inaccurate at this point. - if (expectedValue < 9007199254740992 && -9007199254740992 < expectedValue) - { - Assert.Equal(expectedValue.ToString(), bigInteger.ToString()); - } + actualValue = (BigInteger)testValue; - if (!float.IsInfinity((float)expectedValue)) - { - Assert.Equal((double)(expectedValue + 1), (double)(bigInteger + 1)); - Assert.Equal((double)(expectedValue - 1), (double)(bigInteger - 1)); - } - - VerifyBigIntegerUsingIdentities(bigInteger, 0 == expectedValue); + Assert.Equal(expectedValue, actualValue); } - private static void VerifyDecimalExplicitCastToBigInteger(decimal value) + public static IEnumerable RunDecimalImplicitCastToBigIntegerTestSources { - decimal expectedValue; - BigInteger bigInteger; - - if (value < 0) - { - expectedValue = Math.Ceiling(value); - } - else + get { - expectedValue = Math.Floor(value); - } + yield return new object[] { decimal.MinValue, new BigInteger(decimal.MinValue) }; + yield return new object[] { decimal.MaxValue, new BigInteger(decimal.MaxValue) }; + yield return new object[] { -1, new BigInteger(-1) }; - bigInteger = (BigInteger)value; + decimal value; + value = new decimal(0, 0, 0, false, 28); + yield return new object[] { value, new BigInteger(value) }; - Assert.Equal(expectedValue.ToString(), bigInteger.ToString()); - Assert.Equal(expectedValue, (decimal)bigInteger); + yield return new object[] { 0, new BigInteger(0) }; - VerifyBigIntegerUsingIdentities(bigInteger, 0 == expectedValue); + value = new decimal(1, 0, 0, false, 28); + yield return new object[] { value, new BigInteger(value) }; - if (expectedValue != Math.Floor(decimal.MaxValue)) - { - Assert.Equal((decimal)(expectedValue + 1), (decimal)(bigInteger + 1)); - } + value = 1 - new decimal(1, 0, 0, false, 28); + yield return new object[] { value, new BigInteger(value) }; - if (expectedValue != Math.Ceiling(decimal.MinValue)) - { - Assert.Equal((decimal)(expectedValue - 1), (decimal)(bigInteger - 1)); + value = new decimal(1, 0, 0, false, 0); + yield return new object[] { value, new BigInteger(value) }; + + yield return new object[] { 1, new BigInteger(1) }; + + value = 1 + new decimal(1, 0, 0, false, 28); + yield return new object[] { value, new BigInteger(value) }; + value = 2 - new decimal(1, 0, 0, false, 28); + yield return new object[] { value, new BigInteger(value) }; + for (int i = 0; i < NumberOfRandomIterations; i++) + { + decimal currentValue = new decimal( + s_random.Next(int.MinValue, int.MaxValue), + s_random.Next(int.MinValue, int.MaxValue), + s_random.Next(int.MinValue, int.MaxValue), + true, + (byte)s_random.Next(0, 29)); + yield return new object[] { currentValue, new BigInteger(currentValue) }; + } + for (int i = 0; i < NumberOfRandomIterations; i++) + { + decimal currentValue = new decimal( + s_random.Next(int.MinValue, int.MaxValue), + s_random.Next(int.MinValue, int.MaxValue), + s_random.Next(int.MinValue, int.MaxValue), + false, + (byte)s_random.Next(0, 29)); + yield return new object[] { currentValue, new BigInteger(currentValue) }; + } } } - private static void VerifyBigIntegerUsingIdentities(BigInteger bigInteger, bool isZero) + [Theory] + [MemberData(nameof(RunDecimalImplicitCastToBigIntegerTestSources))] + public static void RunDecimalExplicitCastToBigIntegerTests(decimal testValue, BigInteger expectedValue) { - BigInteger tempBigInteger = new BigInteger(bigInteger.ToByteArray()); - - Assert.Equal(bigInteger, tempBigInteger); - - if (isZero) - { - Assert.Equal(BigInteger.Zero, bigInteger); - } - else - { - Assert.NotEqual(BigInteger.Zero, bigInteger); - - // x/x = 1 - Assert.Equal(BigInteger.One, bigInteger / bigInteger); - } - - // (x + 1) - 1 = x - Assert.Equal(bigInteger, (bigInteger + BigInteger.One) - BigInteger.One); - - // (x + 1) - x = 1 - Assert.Equal(BigInteger.One, (bigInteger + BigInteger.One) - bigInteger); - - // x - x = 0 - Assert.Equal(BigInteger.Zero, bigInteger - bigInteger); - - // x + x = 2x - Assert.Equal(2 * bigInteger, bigInteger + bigInteger); + BigInteger actualValue; - // x/1 = x - Assert.Equal(bigInteger, bigInteger / BigInteger.One); + actualValue = (BigInteger)testValue; - // 1 * x = x - Assert.Equal(bigInteger, BigInteger.One * bigInteger); + Assert.Equal(expectedValue, actualValue); } } } From ca332dc92b7993ed1b60abe7def1cc8dbce4854d Mon Sep 17 00:00:00 2001 From: Maksim Golev Date: Fri, 16 Jul 2021 03:59:11 +0400 Subject: [PATCH 04/10] Adding testcase for reproducing bug. (#49611) --- .../System.Runtime.Numerics/tests/BigInteger/cast_from.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/System.Runtime.Numerics/tests/BigInteger/cast_from.cs b/src/libraries/System.Runtime.Numerics/tests/BigInteger/cast_from.cs index ad3f174fa584e..ed7b215181471 100644 --- a/src/libraries/System.Runtime.Numerics/tests/BigInteger/cast_from.cs +++ b/src/libraries/System.Runtime.Numerics/tests/BigInteger/cast_from.cs @@ -426,6 +426,7 @@ public static IEnumerable RunDoubleExplicitCastFromBigIntegerTestSourc yield return new object[] { new BigInteger(-1.0), -1.0 }; yield return new object[] { new BigInteger(0.0), 0.0 }; yield return new object[] { new BigInteger(1.0), 1.0 }; + yield return new object[] { new BigInteger(4611686018427387903), 4611686018427387903 }; for (int i = 0; i < NumberOfRandomIterations; i++) { double currentValue = double.MinValue * s_random.NextDouble(); From 6d60918915b64cba7568353ce1c3589c8f183009 Mon Sep 17 00:00:00 2001 From: Maksim Golev Date: Fri, 16 Jul 2021 05:37:24 +0400 Subject: [PATCH 05/10] Splitting method for convert BigInteger to Double. (#49611) --- .../src/System/Numerics/BigInteger.cs | 108 ++++++++++++++---- 1 file changed, 84 insertions(+), 24 deletions(-) diff --git a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs index aa90a8bbb1f32..7f9341a89f695 100644 --- a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs +++ b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs @@ -1799,35 +1799,26 @@ public static explicit operator double(BigInteger value) int sign = value._sign; uint[]? bits = value._bits; + double returnValue; - if (bits == null) - return sign; - - int length = bits.Length; - - // The maximum exponent for doubles is 1023, which corresponds to a uint bit length of 32. - // All BigIntegers with bits[] longer than 32 evaluate to Double.Infinity (or NegativeInfinity). - // Cases where the exponent is between 1024 and 1035 are handled in NumericsHelpers.GetDoubleFromParts. - const int InfinityLength = 1024 / kcbitUint; - - if (length > InfinityLength) + if (IsEmpty(bits)) { - if (sign == 1) - return double.PositiveInfinity; + returnValue = sign; + } + else + { + int length = bits.Length; + if (!TryGetInfinity(length, sign, out double? rawValue)) + { + returnValue = ConvertToDouble(bits, length, sign); + } else - return double.NegativeInfinity; + { + returnValue = rawValue.Value; + } } - ulong h = bits[length - 1]; - ulong m = length > 1 ? bits[length - 2] : 0; - ulong l = length > 2 ? bits[length - 3] : 0; - - int z = NumericsHelpers.CbitHighZero((uint)h); - - int exp = (length - 2) * 32 - z; - ulong man = (h << 32 + z) | (m << z) | (l >> 32 - z); - - return NumericsHelpers.GetDoubleFromParts(sign, exp, man); + return returnValue; } public static explicit operator decimal(BigInteger value) @@ -2433,6 +2424,27 @@ public long GetBitLength() return bitLength - 1; } + private static double ConvertToDouble(uint[] bits, + int length, + int sign) + { + ulong highBit, middleBit, lowBit; + double returnValue; + + highBit = bits[length - 1]; + middleBit = length > 1 ? bits[length - 2] : 0; + lowBit = length > 2 ? bits[length - 3] : 0; + + int z = NumericsHelpers.CbitHighZero((uint)highBit); + + int exp = (length - 2) * 32 - z; + ulong man = (highBit << 32 + z) | (middleBit << z) | (lowBit >> 32 - z); + + returnValue = NumericsHelpers.GetDoubleFromParts(sign, exp, man); + + return returnValue; + } + /// /// Encapsulate the logic of normalizing the "small" and "large" forms of BigInteger /// into the "large" form so that Bit Manipulation algorithms can be simplified. @@ -2461,6 +2473,54 @@ private static bool GetPartsForBitManipulation(ref BigInteger x, ref Span return x._sign < 0; } + private static bool IsEmpty([NotNullWhen(false)] uint[]? bits) + { + bool returnValue; + + if (bits == null) + { + returnValue = true; + } + else + { + returnValue = false; + } + + return returnValue; + } + + private static bool TryGetInfinity(int length, + int sign, + [NotNullWhen(true)] out double? infinityValue) + { + bool returnValue; + + // The maximum exponent for doubles is 1023, which corresponds to a uint bit length of 32. + // All BigIntegers with bits[] longer than 32 evaluate to Double.Infinity (or NegativeInfinity). + // Cases where the exponent is between 1024 and 1035 are handled in NumericsHelpers.GetDoubleFromParts. + const int InfinityLength = 1024 / kcbitUint; + + if (length > InfinityLength) + { + if (sign == 1) + { + infinityValue = double.PositiveInfinity; + } + else + { + infinityValue = double.NegativeInfinity; + } + returnValue = true; + } + else + { + infinityValue = null; + returnValue = false; + } + + return returnValue; + } + internal static int GetDiffLength(uint[] rgu1, uint[] rgu2, int cu) { for (int iv = cu; --iv >= 0;) From 5157bb17094ac83d6ac74f9a4ec61464e1dabb31 Mon Sep 17 00:00:00 2001 From: Maksim Golev Date: Sat, 17 Jul 2021 10:26:55 +0400 Subject: [PATCH 06/10] Base fixes of invalid BigInteger casting to Double. (#49611) --- .../src/System/Numerics/BigInteger.cs | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs index 7f9341a89f695..19ea4791c81fb 100644 --- a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs +++ b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs @@ -2428,19 +2428,28 @@ private static double ConvertToDouble(uint[] bits, int length, int sign) { - ulong highBit, middleBit, lowBit; - double returnValue; + ulong highBit, middleBit; + ulong nonZeroDigit; + int leftShiftingSize; + double unsignedNumber, returnValue; + + const int NonZeroDigitsCountOfUInt32 = 32; highBit = bits[length - 1]; middleBit = length > 1 ? bits[length - 2] : 0; - lowBit = length > 2 ? bits[length - 3] : 0; - int z = NumericsHelpers.CbitHighZero((uint)highBit); + leftShiftingSize = (length - 2) * NonZeroDigitsCountOfUInt32; + nonZeroDigit = (highBit << NonZeroDigitsCountOfUInt32) | middleBit; + unsignedNumber = Math.ScaleB(nonZeroDigit, leftShiftingSize); - int exp = (length - 2) * 32 - z; - ulong man = (highBit << 32 + z) | (middleBit << z) | (lowBit >> 32 - z); - - returnValue = NumericsHelpers.GetDoubleFromParts(sign, exp, man); + if (sign < 0) + { + returnValue = -unsignedNumber; + } + else + { + returnValue = unsignedNumber; + } return returnValue; } From dbbaf21e2478f7477b8763318241917fed4dc22e Mon Sep 17 00:00:00 2001 From: Maksim Golev Date: Tue, 27 Jul 2021 18:36:18 +0400 Subject: [PATCH 07/10] Removing needless method and adding an argument about the reason for the broken test. (#49611) --- .../tests/BigInteger/log.cs | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/libraries/System.Runtime.Numerics/tests/BigInteger/log.cs b/src/libraries/System.Runtime.Numerics/tests/BigInteger/log.cs index 37cae18d6c85c..cb3213e34e7f2 100644 --- a/src/libraries/System.Runtime.Numerics/tests/BigInteger/log.cs +++ b/src/libraries/System.Runtime.Numerics/tests/BigInteger/log.cs @@ -177,25 +177,6 @@ private static void VerifyLogString(string opstring) } } - private static void VerifyIdentityString(string opstring1, string opstring2) - { - StackCalc sc1 = new StackCalc(opstring1); - while (sc1.DoNextOperation()) - { - //Run the full calculation - sc1.DoNextOperation(); - } - - StackCalc sc2 = new StackCalc(opstring2); - while (sc2.DoNextOperation()) - { - //Run the full calculation - sc2.DoNextOperation(); - } - - Assert.Equal(sc1.snCalc.Peek().ToString(), sc2.snCalc.Peek().ToString()); - } - private static byte[] GetRandomByteArray(Random random) { return GetRandomByteArray(random, random.Next(0, 100)); @@ -206,6 +187,7 @@ private static byte[] GetRandomByteArray(Random random, int size) return MyBigIntImp.GetRandomByteArray(random, size); } + //Be carefully, this method can generate byte array, which can not be accurately presented by double. private static byte[] GetRandomPosByteArray(Random random, int size) { byte[] value = new byte[size]; From 8c083a0210426f2c997b61d56c5d2aa9d2e0100a Mon Sep 17 00:00:00 2001 From: Maksim Golev Date: Tue, 27 Jul 2021 22:09:55 +0400 Subject: [PATCH 08/10] Switching to TheoryAttribute for testing Log of BigInteger. (#49611) --- .../tests/BigInteger/log.cs | 259 +++++++++--------- 1 file changed, 137 insertions(+), 122 deletions(-) diff --git a/src/libraries/System.Runtime.Numerics/tests/BigInteger/log.cs b/src/libraries/System.Runtime.Numerics/tests/BigInteger/log.cs index cb3213e34e7f2..f6097349a6931 100644 --- a/src/libraries/System.Runtime.Numerics/tests/BigInteger/log.cs +++ b/src/libraries/System.Runtime.Numerics/tests/BigInteger/log.cs @@ -1,141 +1,188 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections.Generic; using Xunit; namespace System.Numerics.Tests { public class logTest { - private static int s_samples = 10; + private const int NumberOfRandomIterations = 10; private static Random s_random = new Random(100); - [Fact] - public static void RunLogTests() + public static IEnumerable RunLogOfZeroIsInfinityTestSources { - byte[] tempByteArray1 = new byte[0]; - byte[] tempByteArray2 = new byte[0]; - BigInteger bi; - - // Log Method - Log(1,+Infinity) - Assert.Equal(0, BigInteger.Log(1, double.PositiveInfinity)); - - // Log Method - Log(1,0) - VerifyLogString("0 1 bLog"); - - // Log Method - Log(0, >1) - for (int i = 0; i < s_samples; i++) + get { - tempByteArray1 = GetRandomPosByteArray(s_random, 10); - VerifyLogString(Print(tempByteArray1) + "0 bLog"); + for (int i = 0; i < NumberOfRandomIterations; i++) + { + double currentValue = s_random.NextDouble(); + yield return new object[] { currentValue }; + } } + } - // Log Method - Log(0, 0>x>1) - for (int i = 0; i < s_samples; i++) - { - Assert.Equal(double.PositiveInfinity, BigInteger.Log(0, s_random.NextDouble())); - } + [Theory] + [MemberData(nameof(RunLogOfZeroIsInfinityTestSources))] + public void RunLogOfZeroIsInfinityTest(double baseValue) + { + Assert.Equal(double.PositiveInfinity, BigInteger.Log(0, baseValue)); + } - // Log Method - base = 0 - for (int i = 0; i < s_samples; i++) + public static IEnumerable RunLogToBaseZeroIsNaNTestSources + { + get { - bi = 1; - while (bi == 1) + for (int i = 0; i < NumberOfRandomIterations; i++) { - bi = new BigInteger(GetRandomPosByteArray(s_random, 8)); + BigInteger currentValue; + do + { + currentValue = new BigInteger(GetRandomPosByteArray(s_random, 8)); + } + while (currentValue == BigInteger.One); + yield return new object[] { currentValue }; } - Assert.True((double.IsNaN(BigInteger.Log(bi, 0)))); } + } - // Log Method - base = 1 - for (int i = 0; i < s_samples; i++) - { - tempByteArray1 = GetRandomByteArray(s_random); - VerifyLogString("1 " + Print(tempByteArray1) + "bLog"); - } + [Theory] + [MemberData(nameof(RunLogToBaseZeroIsNaNTestSources))] + public void RunLogToBaseZeroIsNaNTest(BigInteger testValue) + { + Assert.True((double.IsNaN(BigInteger.Log(testValue, 0)))); + } - // Log Method - base = NaN - for (int i = 0; i < s_samples; i++) + public static IEnumerable RunLogToBaseNaNIsNaNTestSources + { + get { - Assert.True(double.IsNaN(BigInteger.Log(new BigInteger(GetRandomByteArray(s_random, 10)), double.NaN))); + for (int i = 0; i < NumberOfRandomIterations; i++) + { + BigInteger currentValue = new BigInteger(GetRandomByteArray(s_random, 10)); + yield return new object[] { currentValue }; + } } + } - // Log Method - base = +Infinity - for (int i = 0; i < s_samples; i++) + [Theory] + [MemberData(nameof(RunLogToBaseNaNIsNaNTestSources))] + public void RunLogToBaseNaNIsNaNTest(BigInteger testValue) + { + Assert.True((double.IsNaN(BigInteger.Log(testValue, double.NaN)))); + } + + public static IEnumerable RunLogToBasePositiveInfinityIsNaNTestSources + { + get { - Assert.True(double.IsNaN(BigInteger.Log(new BigInteger(GetRandomByteArray(s_random, 10)), double.PositiveInfinity))); + for (int i = 0; i < NumberOfRandomIterations; i++) + { + BigInteger currentValue = new BigInteger(GetRandomByteArray(s_random, 10)); + yield return new object[] { currentValue }; + } } + } - // Log Method - Log(0,1) - VerifyLogString("1 0 bLog"); + [Theory] + [MemberData(nameof(RunLogToBasePositiveInfinityIsNaNTestSources))] + public void RunLogToBasePositiveInfinityIsNaNTest(BigInteger testValue) + { + Assert.True((double.IsNaN(BigInteger.Log(testValue, double.PositiveInfinity)))); + } - // Log Method - base < 0 - for (int i = 0; i < s_samples; i++) + public static IEnumerable RunLogToBasePositiveInfinityTestSources + { + get { - tempByteArray1 = GetRandomByteArray(s_random, 10); - tempByteArray2 = GetRandomNegByteArray(s_random, 1); - VerifyLogString(Print(tempByteArray2) + Print(tempByteArray1) + "bLog"); - Assert.True(double.IsNaN(BigInteger.Log(new BigInteger(GetRandomByteArray(s_random, 10)), -s_random.NextDouble()))); + yield return new object[] { 1, 0 }; } + } - // Log Method - value < 0 - for (int i = 0; i < s_samples; i++) - { - tempByteArray1 = GetRandomNegByteArray(s_random, 10); - tempByteArray2 = GetRandomPosByteArray(s_random, 1); - VerifyLogString(Print(tempByteArray2) + Print(tempByteArray1) + "bLog"); - } + [Theory] + [MemberData(nameof(RunLogToBasePositiveInfinityTestSources))] + public void RunLogToBasePositiveInfinityTest(BigInteger testValue, double expectedValue) + { + Assert.Equal(expectedValue, BigInteger.Log(testValue, double.PositiveInfinity)); + } - // Log Method - Small BigInteger and 0 RunLogToBaseNegativeIsNaNTestSources + { + get { - BigInteger temp = new BigInteger(GetRandomPosByteArray(s_random, 10)); - double newbase = Math.Min(s_random.NextDouble(), 0.5); - Assert.True(ApproxEqual(BigInteger.Log(temp, newbase), Math.Log((double)temp, newbase))); + for (int i = 0; i < NumberOfRandomIterations; i++) + { + BigInteger currentValue = new BigInteger(GetRandomByteArray(s_random, 10)); + double baseValue = -s_random.NextDouble(); + yield return new object[] { currentValue, baseValue }; + } } + } - // Log Method - Large BigInteger and 0 RunLogOfSmallValueTestSources + { + get { - tempByteArray1 = GetRandomPosByteArray(s_random, 2); - tempByteArray2 = GetRandomPosByteArray(s_random, 3); - VerifyLogString(Print(tempByteArray1) + Print(tempByteArray2) + "bLog"); + for (int i = 0; i < NumberOfRandomIterations; i++) + { + BigInteger currentValue = new BigInteger(GetRandomByteArray(s_random, 10)); + double baseValue = Math.Min(s_random.NextDouble(), 0.5); + double expectedValue = Math.Log((double)currentValue, baseValue); + yield return new object[] { currentValue, baseValue, expectedValue }; + } } + } - // Log Method - one small and one large BigIntegers - for (int i = 0; i < s_samples; i++) - { - tempByteArray1 = GetRandomPosByteArray(s_random, 1); - tempByteArray2 = GetRandomPosByteArray(s_random, s_random.Next(1, 100)); - VerifyLogString(Print(tempByteArray1) + Print(tempByteArray2) + "bLog"); - } + [Theory] + [MemberData(nameof(RunLogOfSmallValueTestSources))] + public void RunLogOfSmallValueTest(BigInteger testValue, double baseValue, double expectedValue) + { + Assert.True(ApproxEqual(BigInteger.Log(testValue, baseValue), expectedValue)); + } - // Log Method - two large BigIntegers - for (int i = 0; i < s_samples; i++) + public static IEnumerable RunLogOfLargeValueTestSources + { + get { - tempByteArray1 = GetRandomPosByteArray(s_random, s_random.Next(1, 100)); - tempByteArray2 = GetRandomPosByteArray(s_random, s_random.Next(1, 100)); - VerifyLogString(Print(tempByteArray1) + Print(tempByteArray2) + "bLog"); + for (int i = 0; i < NumberOfRandomIterations; i++) + { + BigInteger currentValue = new BigInteger(GetRandomPosByteArray(s_random, s_random.Next(1, 100))); + double baseValue = Math.Min(s_random.NextDouble(), 0.5); + double expectedValue = Math.Log((double)currentValue, baseValue); + yield return new object[] { currentValue, baseValue, expectedValue }; + } } + } - // Log Method - Very Large BigInteger 1 << 128 << Int.MaxValue and 2 - LargeValueLogTests(128, 1); + [Theory] + [MemberData(nameof(RunLogOfLargeValueTestSources))] + public void RunLogOfLargeValueTest(BigInteger testValue, double baseValue, double expectedValue) + { + Assert.True(ApproxEqual(BigInteger.Log(testValue, baseValue), expectedValue)); + } + public static IEnumerable RunLargeValueLogTestSources + { + get + { + yield return new object[] { 128, 1, 0, 1 }; + yield return new object[] { 0, 4, 64, 3 }; + } } - [Fact] - [OuterLoop] - public static void RunLargeValueLogTests() + [Theory] + [MemberData(nameof(RunLargeValueLogTestSources))] + public void RunLargeValueLogTest(int startShift, int bigShiftLoopLimit, int smallShift, int smallShiftLoopLimit) { - LargeValueLogTests(0, 4, 64, 3); + LargeValueLogTests(startShift, bigShiftLoopLimit, smallShift, smallShiftLoopLimit); } /// @@ -168,20 +215,6 @@ private static void LargeValueLogTests(int startShift, int bigShiftLoopLimit, in } } - private static void VerifyLogString(string opstring) - { - StackCalc sc = new StackCalc(opstring); - while (sc.DoNextOperation()) - { - Assert.Equal(sc.snCalc.Peek().ToString(), sc.myCalc.Peek().ToString()); - } - } - - private static byte[] GetRandomByteArray(Random random) - { - return GetRandomByteArray(random, random.Next(0, 100)); - } - private static byte[] GetRandomByteArray(Random random, int size) { return MyBigIntImp.GetRandomByteArray(random, size); @@ -201,24 +234,6 @@ private static byte[] GetRandomPosByteArray(Random random, int size) return value; } - private static byte[] GetRandomNegByteArray(Random random, int size) - { - byte[] value = new byte[size]; - - for (int i = 0; i < value.Length; ++i) - { - value[i] = (byte)random.Next(0, 256); - } - value[value.Length - 1] |= 0x80; - - return value; - } - - private static string Print(byte[] bytes) - { - return MyBigIntImp.Print(bytes); - } - private static bool ApproxEqual(double value1, double value2) { //Special case values; From ed7ebccbd0901085463a628b63f8e4316c7b4bc6 Mon Sep 17 00:00:00 2001 From: Maksim Golev Date: Mon, 2 Aug 2021 10:31:59 +0400 Subject: [PATCH 09/10] Switching to raw Assert for simplification analysis of failed tests of BigInteger. (#49611) --- .../tests/BigInteger/MyBigInt.cs | 12 ++++ .../tests/BigInteger/log.cs | 65 ++++--------------- 2 files changed, 24 insertions(+), 53 deletions(-) diff --git a/src/libraries/System.Runtime.Numerics/tests/BigInteger/MyBigInt.cs b/src/libraries/System.Runtime.Numerics/tests/BigInteger/MyBigInt.cs index cd4a578fab910..101a57a49a6d7 100644 --- a/src/libraries/System.Runtime.Numerics/tests/BigInteger/MyBigInt.cs +++ b/src/libraries/System.Runtime.Numerics/tests/BigInteger/MyBigInt.cs @@ -8,6 +8,8 @@ namespace System.Numerics.Tests { public static class MyBigIntImp { + private const byte NegativeResetter = 0b0111_1111; + public static BigInteger DoUnaryOperatorMine(BigInteger num1, string op) { List bytes1 = new List(num1.ToByteArray()); @@ -943,6 +945,16 @@ public static byte[] GetRandomByteArray(Random random, int size) return value; } + public static byte[] GetRandomPosByteArray(Random random, int size) + { + byte[] returnValue; + + returnValue = GetRandomByteArray(random, size); + returnValue[returnValue.Length - 1] &= NegativeResetter; + + return returnValue; + } + public static BigInteger ApproximateBigInteger(double value) { //Special case values; diff --git a/src/libraries/System.Runtime.Numerics/tests/BigInteger/log.cs b/src/libraries/System.Runtime.Numerics/tests/BigInteger/log.cs index f6097349a6931..b16c2caa8d7b4 100644 --- a/src/libraries/System.Runtime.Numerics/tests/BigInteger/log.cs +++ b/src/libraries/System.Runtime.Numerics/tests/BigInteger/log.cs @@ -9,6 +9,7 @@ namespace System.Numerics.Tests public class logTest { private const int NumberOfRandomIterations = 10; + private const int RequiredPrecision = 15; private static Random s_random = new Random(100); public static IEnumerable RunLogOfZeroIsInfinityTestSources @@ -39,7 +40,7 @@ public static IEnumerable RunLogToBaseZeroIsNaNTestSources BigInteger currentValue; do { - currentValue = new BigInteger(GetRandomPosByteArray(s_random, 8)); + currentValue = new BigInteger(MyBigIntImp.GetRandomPosByteArray(s_random, 8)); } while (currentValue == BigInteger.One); yield return new object[] { currentValue }; @@ -60,7 +61,7 @@ public static IEnumerable RunLogToBaseNaNIsNaNTestSources { for (int i = 0; i < NumberOfRandomIterations; i++) { - BigInteger currentValue = new BigInteger(GetRandomByteArray(s_random, 10)); + BigInteger currentValue = new BigInteger(MyBigIntImp.GetRandomByteArray(s_random, 10)); yield return new object[] { currentValue }; } } @@ -79,7 +80,7 @@ public static IEnumerable RunLogToBasePositiveInfinityIsNaNTestSources { for (int i = 0; i < NumberOfRandomIterations; i++) { - BigInteger currentValue = new BigInteger(GetRandomByteArray(s_random, 10)); + BigInteger currentValue = new BigInteger(MyBigIntImp.GetRandomByteArray(s_random, 10)); yield return new object[] { currentValue }; } } @@ -113,7 +114,7 @@ public static IEnumerable RunLogToBaseNegativeIsNaNTestSources { for (int i = 0; i < NumberOfRandomIterations; i++) { - BigInteger currentValue = new BigInteger(GetRandomByteArray(s_random, 10)); + BigInteger currentValue = new BigInteger(MyBigIntImp.GetRandomByteArray(s_random, 10)); double baseValue = -s_random.NextDouble(); yield return new object[] { currentValue, baseValue }; } @@ -133,7 +134,7 @@ public static IEnumerable RunLogOfSmallValueTestSources { for (int i = 0; i < NumberOfRandomIterations; i++) { - BigInteger currentValue = new BigInteger(GetRandomByteArray(s_random, 10)); + BigInteger currentValue = new BigInteger(MyBigIntImp.GetRandomByteArray(s_random, 10)); double baseValue = Math.Min(s_random.NextDouble(), 0.5); double expectedValue = Math.Log((double)currentValue, baseValue); yield return new object[] { currentValue, baseValue, expectedValue }; @@ -145,7 +146,7 @@ public static IEnumerable RunLogOfSmallValueTestSources [MemberData(nameof(RunLogOfSmallValueTestSources))] public void RunLogOfSmallValueTest(BigInteger testValue, double baseValue, double expectedValue) { - Assert.True(ApproxEqual(BigInteger.Log(testValue, baseValue), expectedValue)); + Assert.Equal(expectedValue, BigInteger.Log(testValue, baseValue), RequiredPrecision); } public static IEnumerable RunLogOfLargeValueTestSources @@ -154,7 +155,7 @@ public static IEnumerable RunLogOfLargeValueTestSources { for (int i = 0; i < NumberOfRandomIterations; i++) { - BigInteger currentValue = new BigInteger(GetRandomPosByteArray(s_random, s_random.Next(1, 100))); + BigInteger currentValue = new BigInteger(MyBigIntImp.GetRandomPosByteArray(s_random, s_random.Next(1, 100))); double baseValue = Math.Min(s_random.NextDouble(), 0.5); double expectedValue = Math.Log((double)currentValue, baseValue); yield return new object[] { currentValue, baseValue, expectedValue }; @@ -166,7 +167,7 @@ public static IEnumerable RunLogOfLargeValueTestSources [MemberData(nameof(RunLogOfLargeValueTestSources))] public void RunLogOfLargeValueTest(BigInteger testValue, double baseValue, double expectedValue) { - Assert.True(ApproxEqual(BigInteger.Log(testValue, baseValue), expectedValue)); + Assert.Equal(expectedValue, BigInteger.Log(testValue, baseValue), RequiredPrecision); } public static IEnumerable RunLargeValueLogTestSources @@ -195,8 +196,9 @@ public void RunLargeValueLogTest(int startShift, int bigShiftLoopLimit, int smal /// private static void LargeValueLogTests(int startShift, int bigShiftLoopLimit, int smallShift = 0, int smallShiftLoopLimit = 1) { + const double logbase = 2D; BigInteger init = BigInteger.One << startShift; - double logbase = 2D; + for (int i = 0; i < smallShiftLoopLimit; i++) { @@ -209,53 +211,10 @@ private static void LargeValueLogTests(int startShift, int bigShiftLoopLimit, in (double)startShift + smallShift * (double)(i + 1) + (int.MaxValue / 10) * (double)(j + 1); - Assert.True(ApproxEqual(BigInteger.Log(temp, logbase), expected)); + Assert.Equal(expected, BigInteger.Log(temp, logbase), RequiredPrecision); } } } - - private static byte[] GetRandomByteArray(Random random, int size) - { - return MyBigIntImp.GetRandomByteArray(random, size); - } - - //Be carefully, this method can generate byte array, which can not be accurately presented by double. - private static byte[] GetRandomPosByteArray(Random random, int size) - { - byte[] value = new byte[size]; - - for (int i = 0; i < value.Length; i++) - { - value[i] = (byte)random.Next(0, 256); - } - value[value.Length - 1] &= 0x7F; - - return value; - } - - private static bool ApproxEqual(double value1, double value2) - { - //Special case values; - if (double.IsNaN(value1)) - { - return double.IsNaN(value2); - } - if (double.IsNegativeInfinity(value1)) - { - return double.IsNegativeInfinity(value2); - } - if (double.IsPositiveInfinity(value1)) - { - return double.IsPositiveInfinity(value2); - } - if (value2 == 0) - { - return (value1 == 0); - } - - double result = Math.Abs((value1 / value2) - 1); - return (result <= double.Parse("1e-15")); - } } } From 6ed47f57d9e37a84317616a42c663f9282d6e570 Mon Sep 17 00:00:00 2001 From: Maksim Golev Date: Mon, 2 Aug 2021 10:42:56 +0400 Subject: [PATCH 10/10] Stabilization of tests for BigInteger log. (#49611) --- src/libraries/System.Runtime.Numerics/tests/BigInteger/log.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Runtime.Numerics/tests/BigInteger/log.cs b/src/libraries/System.Runtime.Numerics/tests/BigInteger/log.cs index b16c2caa8d7b4..3119d6d9c553b 100644 --- a/src/libraries/System.Runtime.Numerics/tests/BigInteger/log.cs +++ b/src/libraries/System.Runtime.Numerics/tests/BigInteger/log.cs @@ -9,7 +9,7 @@ namespace System.Numerics.Tests public class logTest { private const int NumberOfRandomIterations = 10; - private const int RequiredPrecision = 15; + private const int RequiredPrecision = 10; private static Random s_random = new Random(100); public static IEnumerable RunLogOfZeroIsInfinityTestSources