diff --git a/EvenPerfectBitScanner.Benchmarks/Pow2ProviderBenchmarks.cs b/EvenPerfectBitScanner.Benchmarks/Pow2ProviderBenchmarks.cs new file mode 100644 index 0000000..c518f50 --- /dev/null +++ b/EvenPerfectBitScanner.Benchmarks/Pow2ProviderBenchmarks.cs @@ -0,0 +1,387 @@ +using System.Numerics; +using System.Runtime.CompilerServices; +using BenchmarkDotNet.Attributes; +using PerfectNumbers.Core; + +namespace EvenPerfectBitScanner.Benchmarks +{ + public class Pow2ProviderBigIntegerBenchmarks + { + [Benchmark(Baseline = true)] + public BigInteger ByShifting() + { + BigInteger result = BigInteger.Zero; + for (int i = 0; i <= 63; i++) + { + result = BigInteger.One << i; + } + + return result; + } + + [Benchmark] + public BigInteger ByMapping() + { + BigInteger result = BigInteger.Zero; + for (int i = 0; i <= 63; i++) + { + result = Pow2Provider.BigInteger(i); + } + + return result; + } + } + + public class Pow2MinusOneeProviderBigIntegerBenchmarks + { + [Benchmark(Baseline = true)] + public BigInteger ByShifting() + { + BigInteger result = BigInteger.Zero; + for (int i = 0; i <= 63; i++) + { + result = (BigInteger.One << i) - BigInteger.One; + } + + return result; + } + + [Benchmark] + public BigInteger ByMapping() + { + BigInteger result = BigInteger.Zero; + for (int i = 0; i <= 63; i++) + { + result = Pow2Provider.BigIntegerMinusOne(i); + } + + return result; + } + } + + public class Pow2ProviderULongBenchmarks + { + public static class ULongNumbers + { + public const ulong TwoMinusOne = 2L - 1L; + public const ulong FourMinusOne = 4L - 1L; + public const ulong EightMinusOne = 8L - 1L; + public const ulong SixteenMinusOne = 16L - 1L; + public const ulong ThirtyTwoMinusOne = 32L - 1L; + public const ulong SixtyFourMinusOne = 64L - 1L; + public const ulong OneHundredTwentyEightMinusOne = 128L - 1L; + public const ulong TwoHundredFiftySixMinusOne = 256L - 1L; + public const ulong FiveHundredTwelveMinusOne = 512L - 1L; + public const ulong OneThousandTwentyFourMinusOne = 1_024L - 1L; + public const ulong TwoThousandFortyEightMinusOne = 2_048L - 1L; + public const ulong FourThousandNinetySixMinusOne = 4_096L - 1L; + public const ulong EightThousandOneHundredNinetyTwoMinusOne = 8_192L - 1L; + public const ulong SixteenThousandThreeHundredEightyFourMinusOne = 16_384L - 1L; + public const ulong ThirtyTwoThousandSevenHundredSixtyEightMinusOne = 32_768L - 1L; + public const ulong SixtyFiveThousandFiveHundredThirtySixMinusOne = 65_536L - 1L; + public const ulong OneHundredThirtyOneThousandSeventyTwoMinusOne = 131_072L - 1L; + public const ulong TwoHundredSixtyTwoThousandOneHundredFortyFourMinusOne = 262_144L - 1L; + public const ulong FiveHundredTwentyFourThousandTwoHundredEightyEightMinusOne = 524_288L - 1L; + public const ulong OneMillionFortyEightThousandFiveHundredSeventySixMinusOne = 1_048_576L - 1L; + public const ulong TwoMillionNinetySevenThousandOneHundredFiftyTwoMinusOne = 2_097_152L - 1L; + public const ulong FourMillionOneHundredNinetyFourThousandThreeHundredFourMinusOne = 4_194_304L - 1L; + public const ulong EightMillionThreeHundredEightyEightThousandSixHundredEightMinusOne = 8_388_608L - 1L; + public const ulong SixteenMillionSevenHundredSeventySevenThousandTwoHundredSixteenMinusOne = 16_777_216L - 1L; + public const ulong ThirtyThreeMillionFiveHundredFiftyFourThousandFourHundredThirtyTwoMinusOne = 33_554_432L - 1L; + public const ulong SixtySevenMillionOneHundredEightThousandEightHundredSixtyFourMinusOne = 67_108_864L - 1L; + public const ulong OneHundredThirtyFourMillionTwoHundredSeventeenThousandSevenHundredTwentyEightMinusOne = 134_217_728L - 1L; + public const ulong TwoHundredSixtyEightMillionFourHundredThirtyFiveThousandFourHundredFiftySixMinusOne = 268_435_456L - 1L; + public const ulong FiveHundredThirtySixMillionEightHundredSeventyThousandNineHundredTwelveMinusOne = 536_870_912L - 1L; + public const ulong OneBillionSeventyThreeMillionSevenHundredFortyOneThousandEightHundredTwentyFourMinusOne = 1_073_741_824L - 1L; + public const ulong TwoBillionOneHundredFortySevenMillionFourHundredEightyThreeThousandSixHundredFortyEightMinusOne = 2_147_483_648L - 1L; + public const ulong FourBillionTwoHundredNinetyFourMillionNineHundredSixtySevenThousandTwoHundredNinetySixMinusOne = 4_294_967_296L - 1L; + public const ulong EightBillionFiveHundredEightyNineMillionNineHundredThirtyFourThousandFiveHundredNinetyTwoMinusOne = 8_589_934_592L - 1L; + public const ulong SeventeenBillionOneHundredSeventyNineMillionEightHundredSixtyNineThousandOneHundredEightyFourMinusOne = 17_179_869_184L - 1L; + public const ulong ThirtyFourBillionThreeHundredFiftyNineMillionSevenHundredThirtyEightThousandThreeHundredSixtyEightMinusOne = 34_359_738_368L - 1L; + public const ulong SixtyEightBillionSevenHundredNineteenMillionFourHundredSeventySixThousandSevenHundredThirtySixMinusOne = 68_719_476_736L - 1L; + public const ulong OneHundredThirtySevenBillionFourHundredThirtyEightMillionNineHundredFiftyThreeThousandFourHundredSeventyTwoMinusOne = 137_438_953_472L - 1L; + public const ulong TwoHundredSeventyFourBillionEightHundredSeventySevenMillionNineHundredSixThousandNineHundredFortyFourMinusOne = 274_877_906_944L - 1L; + public const ulong FiveHundredFortyNineBillionSevenHundredFiftyFiveMillionEightHundredThirteenThousandEightHundredEightyEightMinusOne = 549_755_813_888L - 1L; + public const ulong OneTrillionNinetyNineBillionFiveHundredElevenMillionSixHundredTwentySevenThousandSevenHundredSeventySixMinusOne = 1_099_511_627_776L - 1L; + public const ulong TwoTrillionOneHundredNinetyNineBillionTwentyThreeMillionTwoHundredFiftyFiveThousandFiveHundredFiftyTwoMinusOne = 2_199_023_255_552L - 1L; + public const ulong FourTrillionThreeHundredNinetyEightBillionFortySixMillionFiveHundredElevenThousandOneHundredFourMinusOne = 4_398_046_511_104L - 1L; + public const ulong EightTrillionSevenHundredNinetySixBillionNinetyThreeMillionTwentyTwoThousandTwoHundredEightMinusOne = 8_796_093_022_208L - 1L; + public const ulong SeventeenTrillionFiveHundredNinetyTwoBillionOneHundredEightySixMillionFortyFourThousandFourHundredSixteenMinusOne = 17_592_186_044_416L - 1L; + public const ulong ThirtyFiveTrillionOneHundredEightyFourBillionThreeHundredSeventyTwoMillionEightyEightThousandEightHundredThirtyTwoMinusOne = 35_184_372_088_832L - 1L; + public const ulong SeventyTrillionThreeHundredSixtyEightBillionSevenHundredFortyFourMillionOneHundredSeventySevenThousandSixHundredSixtyFourMinusOne = 70_368_744_177_664L - 1L; + public const ulong OneHundredFortyTrillionSevenHundredThirtySevenBillionFourHundredEightyEightMillionThreeHundredFiftyFiveThousandThreeHundredTwentyEightMinusOne = 140_737_488_355_328L - 1L; + public const ulong TwoHundredEightyOneTrillionFourHundredSeventyFourBillionNineHundredSeventySixMillionSevenHundredTenThousandSixHundredFiftySixMinusOne = 281_474_976_710_656L - 1L; + public const ulong FiveHundredSixtyTwoTrillionNineHundredFortyNineBillionNineHundredFiftyThreeMillionFourHundredTwentyOneThousandThreeHundredTwelveMinusOne = 562_949_953_421_312L - 1L; + public const ulong OneQuadrillionOneHundredTwentyFiveTrillionEightHundredNinetyNineBillionNineHundredSixMillionEightHundredFortyTwoThousandSixHundredTwentyFourMinusOne = 1_125_899_906_842_624L - 1L; + public const ulong TwoQuadrillionTwoHundredFiftyOneTrillionSevenHundredNinetyNineBillionEightHundredThirteenMillionSixHundredEightyFiveThousandTwoHundredFortyEightMinusOne = 2_251_799_813_685_248L - 1L; + public const ulong FourQuadrillionFiveHundredThreeTrillionFiveHundredNinetyNineBillionSixHundredTwentySevenMillionThreeHundredSeventyThousandFourHundredNinetySixMinusOne = 4_503_599_627_370_496L - 1L; + public const ulong NineQuadrillionSevenTrillionOneHundredNinetyNineBillionTwoHundredFiftyFourMillionSevenHundredFortyThousandNineHundredNinetyTwoMinusOne = 9_007_199_254_740_992L - 1L; + public const ulong EighteenQuadrillionFourteenTrillionThreeHundredNinetyEightBillionFiveHundredEightMillionEightHundredEightyThousandOneHundredEightyFourMinusOne = 18_014_398_509_481_984L - 1L; + public const ulong ThirtySixQuadrillionTwentyEightTrillionSevenHundredNinetySevenBillionSeventeenMillionSevenHundredSixtyThousandThreeHundredSixtyEightMinusOne = 36_028_797_018_963_968L - 1L; + public const ulong SeventyTwoQuadrillionFiftySevenTrillionFiveHundredNinetyFourBillionThirtyFiveMillionFiveHundredTwentyThousandSevenHundredThirtySixMinusOne = 72_057_594_037_927_936L - 1L; + public const ulong OneHundredFortyFourQuadrillionOneHundredFifteenTrillionOneHundredEightyEightBillionSeventyOneMillionFortyOneThousandFourHundredSeventyTwoMinusOne = 144_115_188_075_855_872L - 1L; + public const ulong TwoHundredEightyEightQuadrillionTwoHundredThirtyTrillionThreeHundredSeventySixBillionOneHundredFortyTwoMillionEightyTwoThousandNineHundredFortyFourMinusOne = 288_230_376_151_711_744L - 1L; + public const ulong FiveHundredSeventySixQuadrillionFourHundredSixtyTrillionSevenHundredFiftyTwoBillionTwoHundredEightyFourMillionOneHundredSixtyFiveThousandEightHundredEightyEightMinusOne = 576_460_752_303_423_488L - 1L; + public const ulong OneQuintillionOneHundredFiftyTwoQuadrillionNineHundredTwentyOneTrillionFiveHundredFourBillionSixHundredSixtyEightMillionThreeHundredThirtyOneThousandSevenHundredSeventySixMinusOne = 1_152_921_504_606_846_976L - 1L; + public const ulong TwoQuintillionThreeHundredFiveQuadrillionEightHundredFortyThreeTrillionNineBillionThreeHundredThirtySixMillionSixHundredSixtyThreeThousandFiveHundredFiftyTwoMinusOne = 2_305_843_009_213_693_952L - 1L; + public const ulong FourQuintillionSixHundredElevenQuadrillionSixHundredEightySevenTrillionEightHundredSixteenBillionSixHundredSeventyThreeMillionTwoHundredTwentySevenThousandOneHundredFourMinusOne = 4_611_686_018_427_387_904L - 1L; + public const ulong NineQuintillionTwoHundredTwentyThreeQuadrillionThreeHundredSeventyTwoTrillionThirtySixBillionEightHundredFiftyFourMillionSevenHundredSeventyFiveThousandEightHundredEightMinusOne = 9_223_372_036_854_775_808UL - 1UL; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static ulong ULongMinusOne(int i) => i switch + { + 0 => 0UL, + 1 => ULongNumbers.TwoMinusOne, + 2 => ULongNumbers.FourMinusOne, + 3 => ULongNumbers.EightMinusOne, + 4 => ULongNumbers.SixteenMinusOne, + 5 => ULongNumbers.ThirtyTwoMinusOne, + 6 => ULongNumbers.SixtyFourMinusOne, + 7 => ULongNumbers.OneHundredTwentyEightMinusOne, + 8 => ULongNumbers.TwoHundredFiftySixMinusOne, + 9 => ULongNumbers.FiveHundredTwelveMinusOne, + 10 => ULongNumbers.OneThousandTwentyFourMinusOne, + 11 => ULongNumbers.TwoThousandFortyEightMinusOne, + 12 => ULongNumbers.FourThousandNinetySixMinusOne, + 13 => ULongNumbers.EightThousandOneHundredNinetyTwoMinusOne, + 14 => ULongNumbers.SixteenThousandThreeHundredEightyFourMinusOne, + 15 => ULongNumbers.ThirtyTwoThousandSevenHundredSixtyEightMinusOne, + 16 => ULongNumbers.SixtyFiveThousandFiveHundredThirtySixMinusOne, + 17 => ULongNumbers.OneHundredThirtyOneThousandSeventyTwoMinusOne, + 18 => ULongNumbers.TwoHundredSixtyTwoThousandOneHundredFortyFourMinusOne, + 19 => ULongNumbers.FiveHundredTwentyFourThousandTwoHundredEightyEightMinusOne, + 20 => ULongNumbers.OneMillionFortyEightThousandFiveHundredSeventySixMinusOne, + 21 => ULongNumbers.TwoMillionNinetySevenThousandOneHundredFiftyTwoMinusOne, + 22 => ULongNumbers.FourMillionOneHundredNinetyFourThousandThreeHundredFourMinusOne, + 23 => ULongNumbers.EightMillionThreeHundredEightyEightThousandSixHundredEightMinusOne, + 24 => ULongNumbers.SixteenMillionSevenHundredSeventySevenThousandTwoHundredSixteenMinusOne, + 25 => ULongNumbers.ThirtyThreeMillionFiveHundredFiftyFourThousandFourHundredThirtyTwoMinusOne, + 26 => ULongNumbers.SixtySevenMillionOneHundredEightThousandEightHundredSixtyFourMinusOne, + 27 => ULongNumbers.OneHundredThirtyFourMillionTwoHundredSeventeenThousandSevenHundredTwentyEightMinusOne, + 28 => ULongNumbers.TwoHundredSixtyEightMillionFourHundredThirtyFiveThousandFourHundredFiftySixMinusOne, + 29 => ULongNumbers.FiveHundredThirtySixMillionEightHundredSeventyThousandNineHundredTwelveMinusOne, + 30 => ULongNumbers.OneBillionSeventyThreeMillionSevenHundredFortyOneThousandEightHundredTwentyFourMinusOne, + 31 => ULongNumbers.TwoBillionOneHundredFortySevenMillionFourHundredEightyThreeThousandSixHundredFortyEightMinusOne, + 32 => ULongNumbers.FourBillionTwoHundredNinetyFourMillionNineHundredSixtySevenThousandTwoHundredNinetySixMinusOne, + 33 => ULongNumbers.EightBillionFiveHundredEightyNineMillionNineHundredThirtyFourThousandFiveHundredNinetyTwoMinusOne, + 34 => ULongNumbers.SeventeenBillionOneHundredSeventyNineMillionEightHundredSixtyNineThousandOneHundredEightyFourMinusOne, + 35 => ULongNumbers.ThirtyFourBillionThreeHundredFiftyNineMillionSevenHundredThirtyEightThousandThreeHundredSixtyEightMinusOne, + 36 => ULongNumbers.SixtyEightBillionSevenHundredNineteenMillionFourHundredSeventySixThousandSevenHundredThirtySixMinusOne, + 37 => ULongNumbers.OneHundredThirtySevenBillionFourHundredThirtyEightMillionNineHundredFiftyThreeThousandFourHundredSeventyTwoMinusOne, + 38 => ULongNumbers.TwoHundredSeventyFourBillionEightHundredSeventySevenMillionNineHundredSixThousandNineHundredFortyFourMinusOne, + 39 => ULongNumbers.FiveHundredFortyNineBillionSevenHundredFiftyFiveMillionEightHundredThirteenThousandEightHundredEightyEightMinusOne, + 40 => ULongNumbers.OneTrillionNinetyNineBillionFiveHundredElevenMillionSixHundredTwentySevenThousandSevenHundredSeventySixMinusOne, + 41 => ULongNumbers.TwoTrillionOneHundredNinetyNineBillionTwentyThreeMillionTwoHundredFiftyFiveThousandFiveHundredFiftyTwoMinusOne, + 42 => ULongNumbers.FourTrillionThreeHundredNinetyEightBillionFortySixMillionFiveHundredElevenThousandOneHundredFourMinusOne, + 43 => ULongNumbers.EightTrillionSevenHundredNinetySixBillionNinetyThreeMillionTwentyTwoThousandTwoHundredEightMinusOne, + 44 => ULongNumbers.SeventeenTrillionFiveHundredNinetyTwoBillionOneHundredEightySixMillionFortyFourThousandFourHundredSixteenMinusOne, + 45 => ULongNumbers.ThirtyFiveTrillionOneHundredEightyFourBillionThreeHundredSeventyTwoMillionEightyEightThousandEightHundredThirtyTwoMinusOne, + 46 => ULongNumbers.SeventyTrillionThreeHundredSixtyEightBillionSevenHundredFortyFourMillionOneHundredSeventySevenThousandSixHundredSixtyFourMinusOne, + 47 => ULongNumbers.OneHundredFortyTrillionSevenHundredThirtySevenBillionFourHundredEightyEightMillionThreeHundredFiftyFiveThousandThreeHundredTwentyEightMinusOne, + 48 => ULongNumbers.TwoHundredEightyOneTrillionFourHundredSeventyFourBillionNineHundredSeventySixMillionSevenHundredTenThousandSixHundredFiftySixMinusOne, + 49 => ULongNumbers.FiveHundredSixtyTwoTrillionNineHundredFortyNineBillionNineHundredFiftyThreeMillionFourHundredTwentyOneThousandThreeHundredTwelveMinusOne, + 50 => ULongNumbers.OneQuadrillionOneHundredTwentyFiveTrillionEightHundredNinetyNineBillionNineHundredSixMillionEightHundredFortyTwoThousandSixHundredTwentyFourMinusOne, + 51 => ULongNumbers.TwoQuadrillionTwoHundredFiftyOneTrillionSevenHundredNinetyNineBillionEightHundredThirteenMillionSixHundredEightyFiveThousandTwoHundredFortyEightMinusOne, + 52 => ULongNumbers.FourQuadrillionFiveHundredThreeTrillionFiveHundredNinetyNineBillionSixHundredTwentySevenMillionThreeHundredSeventyThousandFourHundredNinetySixMinusOne, + 53 => ULongNumbers.NineQuadrillionSevenTrillionOneHundredNinetyNineBillionTwoHundredFiftyFourMillionSevenHundredFortyThousandNineHundredNinetyTwoMinusOne, + 54 => ULongNumbers.EighteenQuadrillionFourteenTrillionThreeHundredNinetyEightBillionFiveHundredEightMillionEightHundredEightyThousandOneHundredEightyFourMinusOne, + 55 => ULongNumbers.ThirtySixQuadrillionTwentyEightTrillionSevenHundredNinetySevenBillionSeventeenMillionSevenHundredSixtyThousandThreeHundredSixtyEightMinusOne, + 56 => ULongNumbers.SeventyTwoQuadrillionFiftySevenTrillionFiveHundredNinetyFourBillionThirtyFiveMillionFiveHundredTwentyThousandSevenHundredThirtySixMinusOne, + 57 => ULongNumbers.OneHundredFortyFourQuadrillionOneHundredFifteenTrillionOneHundredEightyEightBillionSeventyOneMillionFortyOneThousandFourHundredSeventyTwoMinusOne, + 58 => ULongNumbers.TwoHundredEightyEightQuadrillionTwoHundredThirtyTrillionThreeHundredSeventySixBillionOneHundredFortyTwoMillionEightyTwoThousandNineHundredFortyFourMinusOne, + 59 => ULongNumbers.FiveHundredSeventySixQuadrillionFourHundredSixtyTrillionSevenHundredFiftyTwoBillionTwoHundredEightyFourMillionOneHundredSixtyFiveThousandEightHundredEightyEightMinusOne, + 60 => ULongNumbers.OneQuintillionOneHundredFiftyTwoQuadrillionNineHundredTwentyOneTrillionFiveHundredFourBillionSixHundredSixtyEightMillionThreeHundredThirtyOneThousandSevenHundredSeventySixMinusOne, + 61 => ULongNumbers.TwoQuintillionThreeHundredFiveQuadrillionEightHundredFortyThreeTrillionNineBillionThreeHundredThirtySixMillionSixHundredSixtyThreeThousandFiveHundredFiftyTwoMinusOne, + 62 => ULongNumbers.FourQuintillionSixHundredElevenQuadrillionSixHundredEightySevenTrillionEightHundredSixteenBillionSixHundredSeventyThreeMillionTwoHundredTwentySevenThousandOneHundredFourMinusOne, + 63 => ULongNumbers.NineQuintillionTwoHundredTwentyThreeQuadrillionThreeHundredSeventyTwoTrillionThirtySixBillionEightHundredFiftyFourMillionSevenHundredSeventyFiveThousandEightHundredEightMinusOne, + _ => throw new ArgumentOutOfRangeException(nameof(i)), + }; + + [Benchmark(Baseline = true)] + public ulong ByShifting() + { + ulong result = 0UL; + for (int i = 0; i <= 63; i++) + { + result = (1UL << i) - 1UL; + } + + return result; + } + + [Benchmark] + public ulong ByMapping() + { + ulong result = 0UL; + for (int i = 0; i <= 63; i++) + { + result = ULongMinusOne(i); + } + + return result; + } + } + + public class Pow2ProviderLongBenchmarks + { + public static class LongNumbers + { + public const long TwoMinusOne = 2L - 1L; + public const long FourMinusOne = 4L - 1L; + public const long EightMinusOne = 8L - 1L; + public const long SixteenMinusOne = 16L - 1L; + public const long ThirtyTwoMinusOne = 32L - 1L; + public const long SixtyFourMinusOne = 64L - 1L; + public const long OneHundredTwentyEightMinusOne = 128L - 1L; + public const long TwoHundredFiftySixMinusOne = 256L - 1L; + public const long FiveHundredTwelveMinusOne = 512L - 1L; + public const long OneThousandTwentyFourMinusOne = 1_024L - 1L; + public const long TwoThousandFortyEightMinusOne = 2_048L - 1L; + public const long FourThousandNinetySixMinusOne = 4_096L - 1L; + public const long EightThousandOneHundredNinetyTwoMinusOne = 8_192L - 1L; + public const long SixteenThousandThreeHundredEightyFourMinusOne = 16_384L - 1L; + public const long ThirtyTwoThousandSevenHundredSixtyEightMinusOne = 32_768L - 1L; + public const long SixtyFiveThousandFiveHundredThirtySixMinusOne = 65_536L - 1L; + public const long OneHundredThirtyOneThousandSeventyTwoMinusOne = 131_072L - 1L; + public const long TwoHundredSixtyTwoThousandOneHundredFortyFourMinusOne = 262_144L - 1L; + public const long FiveHundredTwentyFourThousandTwoHundredEightyEightMinusOne = 524_288L - 1L; + public const long OneMillionFortyEightThousandFiveHundredSeventySixMinusOne = 1_048_576L - 1L; + public const long TwoMillionNinetySevenThousandOneHundredFiftyTwoMinusOne = 2_097_152L - 1L; + public const long FourMillionOneHundredNinetyFourThousandThreeHundredFourMinusOne = 4_194_304L - 1L; + public const long EightMillionThreeHundredEightyEightThousandSixHundredEightMinusOne = 8_388_608L - 1L; + public const long SixteenMillionSevenHundredSeventySevenThousandTwoHundredSixteenMinusOne = 16_777_216L - 1L; + public const long ThirtyThreeMillionFiveHundredFiftyFourThousandFourHundredThirtyTwoMinusOne = 33_554_432L - 1L; + public const long SixtySevenMillionOneHundredEightThousandEightHundredSixtyFourMinusOne = 67_108_864L - 1L; + public const long OneHundredThirtyFourMillionTwoHundredSeventeenThousandSevenHundredTwentyEightMinusOne = 134_217_728L - 1L; + public const long TwoHundredSixtyEightMillionFourHundredThirtyFiveThousandFourHundredFiftySixMinusOne = 268_435_456L - 1L; + public const long FiveHundredThirtySixMillionEightHundredSeventyThousandNineHundredTwelveMinusOne = 536_870_912L - 1L; + public const long OneBillionSeventyThreeMillionSevenHundredFortyOneThousandEightHundredTwentyFourMinusOne = 1_073_741_824L - 1L; + public const long TwoBillionOneHundredFortySevenMillionFourHundredEightyThreeThousandSixHundredFortyEightMinusOne = 2_147_483_648L - 1L; + public const long FourBillionTwoHundredNinetyFourMillionNineHundredSixtySevenThousandTwoHundredNinetySixMinusOne = 4_294_967_296L - 1L; + public const long EightBillionFiveHundredEightyNineMillionNineHundredThirtyFourThousandFiveHundredNinetyTwoMinusOne = 8_589_934_592L - 1L; + public const long SeventeenBillionOneHundredSeventyNineMillionEightHundredSixtyNineThousandOneHundredEightyFourMinusOne = 17_179_869_184L - 1L; + public const long ThirtyFourBillionThreeHundredFiftyNineMillionSevenHundredThirtyEightThousandThreeHundredSixtyEightMinusOne = 34_359_738_368L - 1L; + public const long SixtyEightBillionSevenHundredNineteenMillionFourHundredSeventySixThousandSevenHundredThirtySixMinusOne = 68_719_476_736L - 1L; + public const long OneHundredThirtySevenBillionFourHundredThirtyEightMillionNineHundredFiftyThreeThousandFourHundredSeventyTwoMinusOne = 137_438_953_472L - 1L; + public const long TwoHundredSeventyFourBillionEightHundredSeventySevenMillionNineHundredSixThousandNineHundredFortyFourMinusOne = 274_877_906_944L - 1L; + public const long FiveHundredFortyNineBillionSevenHundredFiftyFiveMillionEightHundredThirteenThousandEightHundredEightyEightMinusOne = 549_755_813_888L - 1L; + public const long OneTrillionNinetyNineBillionFiveHundredElevenMillionSixHundredTwentySevenThousandSevenHundredSeventySixMinusOne = 1_099_511_627_776L - 1L; + public const long TwoTrillionOneHundredNinetyNineBillionTwentyThreeMillionTwoHundredFiftyFiveThousandFiveHundredFiftyTwoMinusOne = 2_199_023_255_552L - 1L; + public const long FourTrillionThreeHundredNinetyEightBillionFortySixMillionFiveHundredElevenThousandOneHundredFourMinusOne = 4_398_046_511_104L - 1L; + public const long EightTrillionSevenHundredNinetySixBillionNinetyThreeMillionTwentyTwoThousandTwoHundredEightMinusOne = 8_796_093_022_208L - 1L; + public const long SeventeenTrillionFiveHundredNinetyTwoBillionOneHundredEightySixMillionFortyFourThousandFourHundredSixteenMinusOne = 17_592_186_044_416L - 1L; + public const long ThirtyFiveTrillionOneHundredEightyFourBillionThreeHundredSeventyTwoMillionEightyEightThousandEightHundredThirtyTwoMinusOne = 35_184_372_088_832L - 1L; + public const long SeventyTrillionThreeHundredSixtyEightBillionSevenHundredFortyFourMillionOneHundredSeventySevenThousandSixHundredSixtyFourMinusOne = 70_368_744_177_664L - 1L; + public const long OneHundredFortyTrillionSevenHundredThirtySevenBillionFourHundredEightyEightMillionThreeHundredFiftyFiveThousandThreeHundredTwentyEightMinusOne = 140_737_488_355_328L - 1L; + public const long TwoHundredEightyOneTrillionFourHundredSeventyFourBillionNineHundredSeventySixMillionSevenHundredTenThousandSixHundredFiftySixMinusOne = 281_474_976_710_656L - 1L; + public const long FiveHundredSixtyTwoTrillionNineHundredFortyNineBillionNineHundredFiftyThreeMillionFourHundredTwentyOneThousandThreeHundredTwelveMinusOne = 562_949_953_421_312L - 1L; + public const long OneQuadrillionOneHundredTwentyFiveTrillionEightHundredNinetyNineBillionNineHundredSixMillionEightHundredFortyTwoThousandSixHundredTwentyFourMinusOne = 1_125_899_906_842_624L - 1L; + public const long TwoQuadrillionTwoHundredFiftyOneTrillionSevenHundredNinetyNineBillionEightHundredThirteenMillionSixHundredEightyFiveThousandTwoHundredFortyEightMinusOne = 2_251_799_813_685_248L - 1L; + public const long FourQuadrillionFiveHundredThreeTrillionFiveHundredNinetyNineBillionSixHundredTwentySevenMillionThreeHundredSeventyThousandFourHundredNinetySixMinusOne = 4_503_599_627_370_496L - 1L; + public const long NineQuadrillionSevenTrillionOneHundredNinetyNineBillionTwoHundredFiftyFourMillionSevenHundredFortyThousandNineHundredNinetyTwoMinusOne = 9_007_199_254_740_992L - 1L; + public const long EighteenQuadrillionFourteenTrillionThreeHundredNinetyEightBillionFiveHundredEightMillionEightHundredEightyThousandOneHundredEightyFourMinusOne = 18_014_398_509_481_984L - 1L; + public const long ThirtySixQuadrillionTwentyEightTrillionSevenHundredNinetySevenBillionSeventeenMillionSevenHundredSixtyThousandThreeHundredSixtyEightMinusOne = 36_028_797_018_963_968L - 1L; + public const long SeventyTwoQuadrillionFiftySevenTrillionFiveHundredNinetyFourBillionThirtyFiveMillionFiveHundredTwentyThousandSevenHundredThirtySixMinusOne = 72_057_594_037_927_936L - 1L; + public const long OneHundredFortyFourQuadrillionOneHundredFifteenTrillionOneHundredEightyEightBillionSeventyOneMillionFortyOneThousandFourHundredSeventyTwoMinusOne = 144_115_188_075_855_872L - 1L; + public const long TwoHundredEightyEightQuadrillionTwoHundredThirtyTrillionThreeHundredSeventySixBillionOneHundredFortyTwoMillionEightyTwoThousandNineHundredFortyFourMinusOne = 288_230_376_151_711_744L - 1L; + public const long FiveHundredSeventySixQuadrillionFourHundredSixtyTrillionSevenHundredFiftyTwoBillionTwoHundredEightyFourMillionOneHundredSixtyFiveThousandEightHundredEightyEightMinusOne = 576_460_752_303_423_488L - 1L; + public const long OneQuintillionOneHundredFiftyTwoQuadrillionNineHundredTwentyOneTrillionFiveHundredFourBillionSixHundredSixtyEightMillionThreeHundredThirtyOneThousandSevenHundredSeventySixMinusOne = 1_152_921_504_606_846_976L - 1L; + public const long TwoQuintillionThreeHundredFiveQuadrillionEightHundredFortyThreeTrillionNineBillionThreeHundredThirtySixMillionSixHundredSixtyThreeThousandFiveHundredFiftyTwoMinusOne = 2_305_843_009_213_693_952L - 1L; + public const long FourQuintillionSixHundredElevenQuadrillionSixHundredEightySevenTrillionEightHundredSixteenBillionSixHundredSeventyThreeMillionTwoHundredTwentySevenThousandOneHundredFourMinusOne = 4_611_686_018_427_387_904L - 1L; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static long LongMinusOne(int i) => i switch + { + 0 => 0L, + 1 => LongNumbers.TwoMinusOne, + 2 => LongNumbers.FourMinusOne, + 3 => LongNumbers.EightMinusOne, + 4 => LongNumbers.SixteenMinusOne, + 5 => LongNumbers.ThirtyTwoMinusOne, + 6 => LongNumbers.SixtyFourMinusOne, + 7 => LongNumbers.OneHundredTwentyEightMinusOne, + 8 => LongNumbers.TwoHundredFiftySixMinusOne, + 9 => LongNumbers.FiveHundredTwelveMinusOne, + 10 => LongNumbers.OneThousandTwentyFourMinusOne, + 11 => LongNumbers.TwoThousandFortyEightMinusOne, + 12 => LongNumbers.FourThousandNinetySixMinusOne, + 13 => LongNumbers.EightThousandOneHundredNinetyTwoMinusOne, + 14 => LongNumbers.SixteenThousandThreeHundredEightyFourMinusOne, + 15 => LongNumbers.ThirtyTwoThousandSevenHundredSixtyEightMinusOne, + 16 => LongNumbers.SixtyFiveThousandFiveHundredThirtySixMinusOne, + 17 => LongNumbers.OneHundredThirtyOneThousandSeventyTwoMinusOne, + 18 => LongNumbers.TwoHundredSixtyTwoThousandOneHundredFortyFourMinusOne, + 19 => LongNumbers.FiveHundredTwentyFourThousandTwoHundredEightyEightMinusOne, + 20 => LongNumbers.OneMillionFortyEightThousandFiveHundredSeventySixMinusOne, + 21 => LongNumbers.TwoMillionNinetySevenThousandOneHundredFiftyTwoMinusOne, + 22 => LongNumbers.FourMillionOneHundredNinetyFourThousandThreeHundredFourMinusOne, + 23 => LongNumbers.EightMillionThreeHundredEightyEightThousandSixHundredEightMinusOne, + 24 => LongNumbers.SixteenMillionSevenHundredSeventySevenThousandTwoHundredSixteenMinusOne, + 25 => LongNumbers.ThirtyThreeMillionFiveHundredFiftyFourThousandFourHundredThirtyTwoMinusOne, + 26 => LongNumbers.SixtySevenMillionOneHundredEightThousandEightHundredSixtyFourMinusOne, + 27 => LongNumbers.OneHundredThirtyFourMillionTwoHundredSeventeenThousandSevenHundredTwentyEightMinusOne, + 28 => LongNumbers.TwoHundredSixtyEightMillionFourHundredThirtyFiveThousandFourHundredFiftySixMinusOne, + 29 => LongNumbers.FiveHundredThirtySixMillionEightHundredSeventyThousandNineHundredTwelveMinusOne, + 30 => LongNumbers.OneBillionSeventyThreeMillionSevenHundredFortyOneThousandEightHundredTwentyFourMinusOne, + 31 => LongNumbers.TwoBillionOneHundredFortySevenMillionFourHundredEightyThreeThousandSixHundredFortyEightMinusOne, + 32 => LongNumbers.FourBillionTwoHundredNinetyFourMillionNineHundredSixtySevenThousandTwoHundredNinetySixMinusOne, + 33 => LongNumbers.EightBillionFiveHundredEightyNineMillionNineHundredThirtyFourThousandFiveHundredNinetyTwoMinusOne, + 34 => LongNumbers.SeventeenBillionOneHundredSeventyNineMillionEightHundredSixtyNineThousandOneHundredEightyFourMinusOne, + 35 => LongNumbers.ThirtyFourBillionThreeHundredFiftyNineMillionSevenHundredThirtyEightThousandThreeHundredSixtyEightMinusOne, + 36 => LongNumbers.SixtyEightBillionSevenHundredNineteenMillionFourHundredSeventySixThousandSevenHundredThirtySixMinusOne, + 37 => LongNumbers.OneHundredThirtySevenBillionFourHundredThirtyEightMillionNineHundredFiftyThreeThousandFourHundredSeventyTwoMinusOne, + 38 => LongNumbers.TwoHundredSeventyFourBillionEightHundredSeventySevenMillionNineHundredSixThousandNineHundredFortyFourMinusOne, + 39 => LongNumbers.FiveHundredFortyNineBillionSevenHundredFiftyFiveMillionEightHundredThirteenThousandEightHundredEightyEightMinusOne, + 40 => LongNumbers.OneTrillionNinetyNineBillionFiveHundredElevenMillionSixHundredTwentySevenThousandSevenHundredSeventySixMinusOne, + 41 => LongNumbers.TwoTrillionOneHundredNinetyNineBillionTwentyThreeMillionTwoHundredFiftyFiveThousandFiveHundredFiftyTwoMinusOne, + 42 => LongNumbers.FourTrillionThreeHundredNinetyEightBillionFortySixMillionFiveHundredElevenThousandOneHundredFourMinusOne, + 43 => LongNumbers.EightTrillionSevenHundredNinetySixBillionNinetyThreeMillionTwentyTwoThousandTwoHundredEightMinusOne, + 44 => LongNumbers.SeventeenTrillionFiveHundredNinetyTwoBillionOneHundredEightySixMillionFortyFourThousandFourHundredSixteenMinusOne, + 45 => LongNumbers.ThirtyFiveTrillionOneHundredEightyFourBillionThreeHundredSeventyTwoMillionEightyEightThousandEightHundredThirtyTwoMinusOne, + 46 => LongNumbers.SeventyTrillionThreeHundredSixtyEightBillionSevenHundredFortyFourMillionOneHundredSeventySevenThousandSixHundredSixtyFourMinusOne, + 47 => LongNumbers.OneHundredFortyTrillionSevenHundredThirtySevenBillionFourHundredEightyEightMillionThreeHundredFiftyFiveThousandThreeHundredTwentyEightMinusOne, + 48 => LongNumbers.TwoHundredEightyOneTrillionFourHundredSeventyFourBillionNineHundredSeventySixMillionSevenHundredTenThousandSixHundredFiftySixMinusOne, + 49 => LongNumbers.FiveHundredSixtyTwoTrillionNineHundredFortyNineBillionNineHundredFiftyThreeMillionFourHundredTwentyOneThousandThreeHundredTwelveMinusOne, + 50 => LongNumbers.OneQuadrillionOneHundredTwentyFiveTrillionEightHundredNinetyNineBillionNineHundredSixMillionEightHundredFortyTwoThousandSixHundredTwentyFourMinusOne, + 51 => LongNumbers.TwoQuadrillionTwoHundredFiftyOneTrillionSevenHundredNinetyNineBillionEightHundredThirteenMillionSixHundredEightyFiveThousandTwoHundredFortyEightMinusOne, + 52 => LongNumbers.FourQuadrillionFiveHundredThreeTrillionFiveHundredNinetyNineBillionSixHundredTwentySevenMillionThreeHundredSeventyThousandFourHundredNinetySixMinusOne, + 53 => LongNumbers.NineQuadrillionSevenTrillionOneHundredNinetyNineBillionTwoHundredFiftyFourMillionSevenHundredFortyThousandNineHundredNinetyTwoMinusOne, + 54 => LongNumbers.EighteenQuadrillionFourteenTrillionThreeHundredNinetyEightBillionFiveHundredEightMillionEightHundredEightyThousandOneHundredEightyFourMinusOne, + 55 => LongNumbers.ThirtySixQuadrillionTwentyEightTrillionSevenHundredNinetySevenBillionSeventeenMillionSevenHundredSixtyThousandThreeHundredSixtyEightMinusOne, + 56 => LongNumbers.SeventyTwoQuadrillionFiftySevenTrillionFiveHundredNinetyFourBillionThirtyFiveMillionFiveHundredTwentyThousandSevenHundredThirtySixMinusOne, + 57 => LongNumbers.OneHundredFortyFourQuadrillionOneHundredFifteenTrillionOneHundredEightyEightBillionSeventyOneMillionFortyOneThousandFourHundredSeventyTwoMinusOne, + 58 => LongNumbers.TwoHundredEightyEightQuadrillionTwoHundredThirtyTrillionThreeHundredSeventySixBillionOneHundredFortyTwoMillionEightyTwoThousandNineHundredFortyFourMinusOne, + 59 => LongNumbers.FiveHundredSeventySixQuadrillionFourHundredSixtyTrillionSevenHundredFiftyTwoBillionTwoHundredEightyFourMillionOneHundredSixtyFiveThousandEightHundredEightyEightMinusOne, + 60 => LongNumbers.OneQuintillionOneHundredFiftyTwoQuadrillionNineHundredTwentyOneTrillionFiveHundredFourBillionSixHundredSixtyEightMillionThreeHundredThirtyOneThousandSevenHundredSeventySixMinusOne, + 61 => LongNumbers.TwoQuintillionThreeHundredFiveQuadrillionEightHundredFortyThreeTrillionNineBillionThreeHundredThirtySixMillionSixHundredSixtyThreeThousandFiveHundredFiftyTwoMinusOne, + 62 => LongNumbers.FourQuintillionSixHundredElevenQuadrillionSixHundredEightySevenTrillionEightHundredSixteenBillionSixHundredSeventyThreeMillionTwoHundredTwentySevenThousandOneHundredFourMinusOne, + _ => throw new ArgumentOutOfRangeException(nameof(i)), + }; + + [Benchmark(Baseline = true)] + public long ByShifting() + { + long result = 0L; + for (int i = 0; i <= 62; i++) + { + result = (1L << i) - 1L; + } + + return result; + } + + [Benchmark] + public long ByMapping() + { + long result = 0L; + for (int i = 0; i <= 62; i++) + { + result = LongMinusOne(i); + } + + return result; + } + } +} \ No newline at end of file diff --git a/PerfectNumbers.Core/BigIntegerNumbers.cs b/PerfectNumbers.Core/BigIntegerNumbers.cs index 984a918..3f7ef2b 100644 --- a/PerfectNumbers.Core/BigIntegerNumbers.cs +++ b/PerfectNumbers.Core/BigIntegerNumbers.cs @@ -6,10 +6,138 @@ namespace PerfectNumbers.Core { public static readonly BigInteger OneShiftedLeft63 = BigInteger.One << 63; public static readonly BigInteger OneShiftedLeft256MinusOne = (BigInteger.One << 256) - BigInteger.One; - public static readonly BigInteger Two = (BigInteger)2; public static readonly BigInteger UlongMaxValue = (BigInteger)ulong.MaxValue; public static readonly BigInteger UlongMaxValuePlusOne = UlongMaxValue + BigInteger.One; public static readonly BigInteger UInt128MaxValue = (BigInteger)UInt128.MaxValue; public static readonly BigInteger UInt128MaxValuePlusOne = UInt128MaxValue + BigInteger.One; + + public static readonly BigInteger Two = 2UL; + public static readonly BigInteger Pow2Exact2 = 4UL; + public static readonly BigInteger Pow2Exact3 = 8UL; + public static readonly BigInteger Pow2Exact4 = 16UL; + public static readonly BigInteger Pow2Exact5 = 32UL; + public static readonly BigInteger Pow2Exact6 = 64UL; + public static readonly BigInteger Pow2Exact7 = 128UL; + public static readonly BigInteger Pow2Exact8 = 256UL; + public static readonly BigInteger Pow2Exact9 = 512UL; + public static readonly BigInteger Pow2Exact10 = 1_024UL; + public static readonly BigInteger Pow2Exact11 = 2_048UL; + public static readonly BigInteger Pow2Exact12 = 4_096UL; + public static readonly BigInteger Pow2Exact13 = 8_192UL; + public static readonly BigInteger Pow2Exact14 = 16_384UL; + public static readonly BigInteger Pow2Exact15 = 32_768UL; + public static readonly BigInteger Pow2Exact16 = 65_536UL; + public static readonly BigInteger Pow2Exact17 = 131_072UL; + public static readonly BigInteger Pow2Exact18 = 262_144UL; + public static readonly BigInteger Pow2Exact19 = 524_288UL; + public static readonly BigInteger Pow2Exact20 = 1_048_576UL; + public static readonly BigInteger Pow2Exact21 = 2_097_152UL; + public static readonly BigInteger Pow2Exact22 = 4_194_304UL; + public static readonly BigInteger Pow2Exact23 = 8_388_608UL; + public static readonly BigInteger Pow2Exact24 = 16_777_216UL; + public static readonly BigInteger Pow2Exact25 = 33_554_432UL; + public static readonly BigInteger Pow2Exact26 = 67_108_864UL; + public static readonly BigInteger Pow2Exact27 = 134_217_728UL; + public static readonly BigInteger Pow2Exact28 = 268_435_456UL; + public static readonly BigInteger Pow2Exact29 = 536_870_912UL; + public static readonly BigInteger Pow2Exact30 = 1_073_741_824UL; + public static readonly BigInteger Pow2Exact31 = 2_147_483_648UL; + public static readonly BigInteger Pow2Exact32 = 4_294_967_296UL; + public static readonly BigInteger Pow2Exact33 = 8_589_934_592UL; + public static readonly BigInteger Pow2Exact34 = 17_179_869_184UL; + public static readonly BigInteger Pow2Exact35 = 34_359_738_368UL; + public static readonly BigInteger Pow2Exact36 = 68_719_476_736UL; + public static readonly BigInteger Pow2Exact37 = 137_438_953_472UL; + public static readonly BigInteger Pow2Exact38 = 274_877_906_944UL; + public static readonly BigInteger Pow2Exact39 = 549_755_813_888UL; + public static readonly BigInteger Pow2Exact40 = 1_099_511_627_776UL; + public static readonly BigInteger Pow2Exact41 = 2_199_023_255_552UL; + public static readonly BigInteger Pow2Exact42 = 4_398_046_511_104UL; + public static readonly BigInteger Pow2Exact43 = 8_796_093_022_208UL; + public static readonly BigInteger Pow2Exact44 = 17_592_186_044_416UL; + public static readonly BigInteger Pow2Exact45 = 35_184_372_088_832UL; + public static readonly BigInteger Pow2Exact46 = 70_368_744_177_664UL; + public static readonly BigInteger Pow2Exact47 = 140_737_488_355_328UL; + public static readonly BigInteger Pow2Exact48 = 281_474_976_710_656UL; + public static readonly BigInteger Pow2Exact49 = 562_949_953_421_312UL; + public static readonly BigInteger Pow2Exact50 = 1_125_899_906_842_624UL; + public static readonly BigInteger Pow2Exact51 = 2_251_799_813_685_248UL; + public static readonly BigInteger Pow2Exact52 = 4_503_599_627_370_496UL; + public static readonly BigInteger Pow2Exact53 = 9_007_199_254_740_992UL; + public static readonly BigInteger Pow2Exact54 = 18_014_398_509_481_984UL; + public static readonly BigInteger Pow2Exact55 = 36_028_797_018_963_968UL; + public static readonly BigInteger Pow2Exact56 = 72_057_594_037_927_936UL; + public static readonly BigInteger Pow2Exact57 = 144_115_188_075_855_872UL; + public static readonly BigInteger Pow2Exact58 = 288_230_376_151_711_744UL; + public static readonly BigInteger Pow2Exact59 = 576_460_752_303_423_488UL; + public static readonly BigInteger Pow2Exact60 = 1_152_921_504_606_846_976UL; + public static readonly BigInteger Pow2Exact61 = 2_305_843_009_213_693_952UL; + public static readonly BigInteger Pow2Exact62 = 4_611_686_018_427_387_904UL; + public static readonly BigInteger Pow2Exact63 = 9_223_372_036_854_775_808UL; + + public static readonly BigInteger Pow2MinusOne1 = 2UL - 1UL; + public static readonly BigInteger Pow2MinusOne2 = 4UL - 1UL; + public static readonly BigInteger Pow2MinusOne3 = 8UL - 1UL; + public static readonly BigInteger Pow2MinusOne4 = 16UL - 1UL; + public static readonly BigInteger Pow2MinusOne5 = 32UL - 1UL; + public static readonly BigInteger Pow2MinusOne6 = 64UL - 1UL; + public static readonly BigInteger Pow2MinusOne7 = 128UL - 1UL; + public static readonly BigInteger Pow2MinusOne8 = 256UL - 1UL; + public static readonly BigInteger Pow2MinusOne9 = 512UL - 1UL; + public static readonly BigInteger Pow2MinusOne10 = 1_024UL - 1UL; + public static readonly BigInteger Pow2MinusOne11 = 2_048UL - 1UL; + public static readonly BigInteger Pow2MinusOne12 = 4_096UL - 1UL; + public static readonly BigInteger Pow2MinusOne13 = 8_192UL - 1UL; + public static readonly BigInteger Pow2MinusOne14 = 16_384UL - 1UL; + public static readonly BigInteger Pow2MinusOne15 = 32_768UL - 1UL; + public static readonly BigInteger Pow2MinusOne16 = 65_536UL - 1UL; + public static readonly BigInteger Pow2MinusOne17 = 131_072UL - 1UL; + public static readonly BigInteger Pow2MinusOne18 = 262_144UL - 1UL; + public static readonly BigInteger Pow2MinusOne19 = 524_288UL - 1UL; + public static readonly BigInteger Pow2MinusOne20 = 1_048_576UL - 1UL; + public static readonly BigInteger Pow2MinusOne21 = 2_097_152UL - 1UL; + public static readonly BigInteger Pow2MinusOne22 = 4_194_304UL - 1UL; + public static readonly BigInteger Pow2MinusOne23 = 8_388_608UL - 1UL; + public static readonly BigInteger Pow2MinusOne24 = 16_777_216UL - 1UL; + public static readonly BigInteger Pow2MinusOne25 = 33_554_432UL - 1UL; + public static readonly BigInteger Pow2MinusOne26 = 67_108_864UL - 1UL; + public static readonly BigInteger Pow2MinusOne27 = 134_217_728UL - 1UL; + public static readonly BigInteger Pow2MinusOne28 = 268_435_456UL - 1UL; + public static readonly BigInteger Pow2MinusOne29 = 536_870_912UL - 1UL; + public static readonly BigInteger Pow2MinusOne30 = 1_073_741_824UL - 1UL; + public static readonly BigInteger Pow2MinusOne31 = 2_147_483_648UL - 1UL; + public static readonly BigInteger Pow2MinusOne32 = 4_294_967_296UL - 1UL; + public static readonly BigInteger Pow2MinusOne33 = 8_589_934_592UL - 1UL; + public static readonly BigInteger Pow2MinusOne34 = 17_179_869_184UL - 1UL; + public static readonly BigInteger Pow2MinusOne35 = 34_359_738_368UL - 1UL; + public static readonly BigInteger Pow2MinusOne36 = 68_719_476_736UL - 1UL; + public static readonly BigInteger Pow2MinusOne37 = 137_438_953_472UL - 1UL; + public static readonly BigInteger Pow2MinusOne38 = 274_877_906_944UL - 1UL; + public static readonly BigInteger Pow2MinusOne39 = 549_755_813_888UL - 1UL; + public static readonly BigInteger Pow2MinusOne40 = 1_099_511_627_776UL - 1UL; + public static readonly BigInteger Pow2MinusOne41 = 2_199_023_255_552UL - 1UL; + public static readonly BigInteger Pow2MinusOne42 = 4_398_046_511_104UL - 1UL; + public static readonly BigInteger Pow2MinusOne43 = 8_796_093_022_208UL - 1UL; + public static readonly BigInteger Pow2MinusOne44 = 17_592_186_044_416UL - 1UL; + public static readonly BigInteger Pow2MinusOne45 = 35_184_372_088_832UL - 1UL; + public static readonly BigInteger Pow2MinusOne46 = 70_368_744_177_664UL - 1UL; + public static readonly BigInteger Pow2MinusOne47 = 140_737_488_355_328UL - 1UL; + public static readonly BigInteger Pow2MinusOne48 = 281_474_976_710_656UL - 1UL; + public static readonly BigInteger Pow2MinusOne49 = 562_949_953_421_312UL - 1UL; + public static readonly BigInteger Pow2MinusOne50 = 1_125_899_906_842_624UL - 1UL; + public static readonly BigInteger Pow2MinusOne51 = 2_251_799_813_685_248UL - 1UL; + public static readonly BigInteger Pow2MinusOne52 = 4_503_599_627_370_496UL - 1UL; + public static readonly BigInteger Pow2MinusOne53 = 9_007_199_254_740_992UL - 1UL; + public static readonly BigInteger Pow2MinusOne54 = 18_014_398_509_481_984UL - 1UL; + public static readonly BigInteger Pow2MinusOne55 = 36_028_797_018_963_968UL - 1UL; + public static readonly BigInteger Pow2MinusOne56 = 72_057_594_037_927_936UL - 1UL; + public static readonly BigInteger Pow2MinusOne57 = 144_115_188_075_855_872UL - 1UL; + public static readonly BigInteger Pow2MinusOne58 = 288_230_376_151_711_744UL - 1UL; + public static readonly BigInteger Pow2MinusOne59 = 576_460_752_303_423_488UL - 1UL; + public static readonly BigInteger Pow2MinusOne60 = 1_152_921_504_606_846_976UL - 1UL; + public static readonly BigInteger Pow2MinusOne61 = 2_305_843_009_213_693_952UL - 1UL; + public static readonly BigInteger Pow2MinusOne62 = 4_611_686_018_427_387_904UL - 1UL; + public static readonly BigInteger Pow2MinusOne63 = 9_223_372_036_854_775_808UL - 1UL; + public static readonly BigInteger Pow2MinusOne1024 = (BigInteger.One << 1024) - BigInteger.One; } } \ No newline at end of file diff --git a/PerfectNumbers.Core/ByDivisor/BitContradictionSolverWithAMultiplier.cs b/PerfectNumbers.Core/ByDivisor/BitContradictionSolverWithAMultiplier.cs index 72a691c..3e46359 100644 --- a/PerfectNumbers.Core/ByDivisor/BitContradictionSolverWithAMultiplier.cs +++ b/PerfectNumbers.Core/ByDivisor/BitContradictionSolverWithAMultiplier.cs @@ -1113,8 +1113,8 @@ internal static class BitContradictionSolverWithAMultiplier return; } - int shift = zeroTailStart + 1 > int.MaxValue ? int.MaxValue : (int)(zeroTailStart + 1); - maxA = (BigInteger.One << shift) - BigInteger.One; + int shift = zeroTailStart + 1L > int.MaxValue ? int.MaxValue : (int)(zeroTailStart + 1L); + maxA = Pow2Provider.BigIntegerMinusOne(shift); minA = BigInteger.Zero; if (zeroTailStart == maxAllowedA) @@ -1122,15 +1122,15 @@ internal static class BitContradictionSolverWithAMultiplier if (top0KnownOne) { shift = maxAllowedA > int.MaxValue ? int.MaxValue : (int)maxAllowedA; - minA = BigInteger.One << shift; } - else if (top0KnownZero && top1KnownOne && maxAllowedA - 1 >= 0) + else if (top0KnownZero && top1KnownOne && maxAllowedA - 1L >= 0) { // zeroTailStart is index from here. We're reusing the variable to limit registry pressure. - zeroTailStart = maxAllowedA - 1; + zeroTailStart = maxAllowedA - 1L; shift = zeroTailStart > int.MaxValue ? int.MaxValue : (int)zeroTailStart; - minA = BigInteger.One << shift; } + + minA = Pow2Provider.BigInteger(shift); } } @@ -1400,7 +1400,7 @@ internal static class BitContradictionSolverWithAMultiplier // This is a necessary condition for q | (2^p - 1) when p >= 1024 (true here). const int ForcedBits = ForcedALowBits; - BigInteger mask = (BigInteger.One << ForcedBits) - BigInteger.One; + BigInteger mask = Pow2Provider.BigIntegerMinusOne(ForcedBits); // Build q (low 1024 bits) from qOneOffsets. q is small anyway, but do it generically. BigInteger qMod2k = BigInteger.Zero; @@ -1408,7 +1408,7 @@ internal static class BitContradictionSolverWithAMultiplier { int bit = qOneOffsets[i]; if (bit >= ForcedBits) break; - qMod2k |= (BigInteger.One << bit); + qMod2k |= Pow2Provider.BigInteger(bit); } // q must be odd for any Mersenne divisor candidate. diff --git a/PerfectNumbers.Core/Pow2Provider.cs b/PerfectNumbers.Core/Pow2Provider.cs new file mode 100644 index 0000000..a788278 --- /dev/null +++ b/PerfectNumbers.Core/Pow2Provider.cs @@ -0,0 +1,146 @@ +using System.Numerics; + +namespace PerfectNumbers.Core +{ + public static class Pow2Provider + { + public static BigInteger BigInteger(int i) => i switch + { + 0 => System.Numerics.BigInteger.One, + 1 => BigIntegerNumbers.Two, + 2 => BigIntegerNumbers.Pow2Exact2, + 3 => BigIntegerNumbers.Pow2Exact3, + 4 => BigIntegerNumbers.Pow2Exact4, + 5 => BigIntegerNumbers.Pow2Exact5, + 6 => BigIntegerNumbers.Pow2Exact6, + 7 => BigIntegerNumbers.Pow2Exact7, + 8 => BigIntegerNumbers.Pow2Exact8, + 9 => BigIntegerNumbers.Pow2Exact9, + 10 => BigIntegerNumbers.Pow2Exact10, + 11 => BigIntegerNumbers.Pow2Exact11, + 12 => BigIntegerNumbers.Pow2Exact12, + 13 => BigIntegerNumbers.Pow2Exact13, + 14 => BigIntegerNumbers.Pow2Exact14, + 15 => BigIntegerNumbers.Pow2Exact15, + 16 => BigIntegerNumbers.Pow2Exact16, + 17 => BigIntegerNumbers.Pow2Exact17, + 18 => BigIntegerNumbers.Pow2Exact18, + 19 => BigIntegerNumbers.Pow2Exact19, + 20 => BigIntegerNumbers.Pow2Exact20, + 21 => BigIntegerNumbers.Pow2Exact21, + 22 => BigIntegerNumbers.Pow2Exact22, + 23 => BigIntegerNumbers.Pow2Exact23, + 24 => BigIntegerNumbers.Pow2Exact24, + 25 => BigIntegerNumbers.Pow2Exact25, + 26 => BigIntegerNumbers.Pow2Exact26, + 27 => BigIntegerNumbers.Pow2Exact27, + 28 => BigIntegerNumbers.Pow2Exact28, + 29 => BigIntegerNumbers.Pow2Exact29, + 30 => BigIntegerNumbers.Pow2Exact30, + 31 => BigIntegerNumbers.Pow2Exact31, + 32 => BigIntegerNumbers.Pow2Exact32, + 33 => BigIntegerNumbers.Pow2Exact33, + 34 => BigIntegerNumbers.Pow2Exact34, + 35 => BigIntegerNumbers.Pow2Exact35, + 36 => BigIntegerNumbers.Pow2Exact36, + 37 => BigIntegerNumbers.Pow2Exact37, + 38 => BigIntegerNumbers.Pow2Exact38, + 39 => BigIntegerNumbers.Pow2Exact39, + 40 => BigIntegerNumbers.Pow2Exact40, + 41 => BigIntegerNumbers.Pow2Exact41, + 42 => BigIntegerNumbers.Pow2Exact42, + 43 => BigIntegerNumbers.Pow2Exact43, + 44 => BigIntegerNumbers.Pow2Exact44, + 45 => BigIntegerNumbers.Pow2Exact45, + 46 => BigIntegerNumbers.Pow2Exact46, + 47 => BigIntegerNumbers.Pow2Exact47, + 48 => BigIntegerNumbers.Pow2Exact48, + 49 => BigIntegerNumbers.Pow2Exact49, + 50 => BigIntegerNumbers.Pow2Exact50, + 51 => BigIntegerNumbers.Pow2Exact51, + 52 => BigIntegerNumbers.Pow2Exact52, + 53 => BigIntegerNumbers.Pow2Exact53, + 54 => BigIntegerNumbers.Pow2Exact54, + 55 => BigIntegerNumbers.Pow2Exact55, + 56 => BigIntegerNumbers.Pow2Exact56, + 57 => BigIntegerNumbers.Pow2Exact57, + 58 => BigIntegerNumbers.Pow2Exact58, + 59 => BigIntegerNumbers.Pow2Exact59, + 60 => BigIntegerNumbers.Pow2Exact60, + 61 => BigIntegerNumbers.Pow2Exact61, + 62 => BigIntegerNumbers.Pow2Exact62, + 63 => BigIntegerNumbers.Pow2Exact63, + _ => throw new ArgumentOutOfRangeException(nameof(i), $"Parameter value {i} is incorrect"), + }; + + public static BigInteger BigIntegerMinusOne(int i) => i switch + { + 0 => System.Numerics.BigInteger.Zero, + 1 => BigIntegerNumbers.Pow2MinusOne1, + 2 => BigIntegerNumbers.Pow2MinusOne2, + 3 => BigIntegerNumbers.Pow2MinusOne3, + 4 => BigIntegerNumbers.Pow2MinusOne4, + 5 => BigIntegerNumbers.Pow2MinusOne5, + 6 => BigIntegerNumbers.Pow2MinusOne6, + 7 => BigIntegerNumbers.Pow2MinusOne7, + 8 => BigIntegerNumbers.Pow2MinusOne8, + 9 => BigIntegerNumbers.Pow2MinusOne9, + 10 => BigIntegerNumbers.Pow2MinusOne10, + 11 => BigIntegerNumbers.Pow2MinusOne11, + 12 => BigIntegerNumbers.Pow2MinusOne12, + 13 => BigIntegerNumbers.Pow2MinusOne13, + 14 => BigIntegerNumbers.Pow2MinusOne14, + 15 => BigIntegerNumbers.Pow2MinusOne15, + 16 => BigIntegerNumbers.Pow2MinusOne16, + 17 => BigIntegerNumbers.Pow2MinusOne17, + 18 => BigIntegerNumbers.Pow2MinusOne18, + 19 => BigIntegerNumbers.Pow2MinusOne19, + 20 => BigIntegerNumbers.Pow2MinusOne20, + 21 => BigIntegerNumbers.Pow2MinusOne21, + 22 => BigIntegerNumbers.Pow2MinusOne22, + 23 => BigIntegerNumbers.Pow2MinusOne23, + 24 => BigIntegerNumbers.Pow2MinusOne24, + 25 => BigIntegerNumbers.Pow2MinusOne25, + 26 => BigIntegerNumbers.Pow2MinusOne26, + 27 => BigIntegerNumbers.Pow2MinusOne27, + 28 => BigIntegerNumbers.Pow2MinusOne28, + 29 => BigIntegerNumbers.Pow2MinusOne29, + 30 => BigIntegerNumbers.Pow2MinusOne30, + 31 => BigIntegerNumbers.Pow2MinusOne31, + 32 => BigIntegerNumbers.Pow2MinusOne32, + 33 => BigIntegerNumbers.Pow2MinusOne33, + 34 => BigIntegerNumbers.Pow2MinusOne34, + 35 => BigIntegerNumbers.Pow2MinusOne35, + 36 => BigIntegerNumbers.Pow2MinusOne36, + 37 => BigIntegerNumbers.Pow2MinusOne37, + 38 => BigIntegerNumbers.Pow2MinusOne38, + 39 => BigIntegerNumbers.Pow2MinusOne39, + 40 => BigIntegerNumbers.Pow2MinusOne40, + 41 => BigIntegerNumbers.Pow2MinusOne41, + 42 => BigIntegerNumbers.Pow2MinusOne42, + 43 => BigIntegerNumbers.Pow2MinusOne43, + 44 => BigIntegerNumbers.Pow2MinusOne44, + 45 => BigIntegerNumbers.Pow2MinusOne45, + 46 => BigIntegerNumbers.Pow2MinusOne46, + 47 => BigIntegerNumbers.Pow2MinusOne47, + 48 => BigIntegerNumbers.Pow2MinusOne48, + 49 => BigIntegerNumbers.Pow2MinusOne49, + 50 => BigIntegerNumbers.Pow2MinusOne50, + 51 => BigIntegerNumbers.Pow2MinusOne51, + 52 => BigIntegerNumbers.Pow2MinusOne52, + 53 => BigIntegerNumbers.Pow2MinusOne53, + 54 => BigIntegerNumbers.Pow2MinusOne54, + 55 => BigIntegerNumbers.Pow2MinusOne55, + 56 => BigIntegerNumbers.Pow2MinusOne56, + 57 => BigIntegerNumbers.Pow2MinusOne57, + 58 => BigIntegerNumbers.Pow2MinusOne58, + 59 => BigIntegerNumbers.Pow2MinusOne59, + 60 => BigIntegerNumbers.Pow2MinusOne60, + 61 => BigIntegerNumbers.Pow2MinusOne61, + 62 => BigIntegerNumbers.Pow2MinusOne62, + 63 => BigIntegerNumbers.Pow2MinusOne63, + 1024 => BigIntegerNumbers.Pow2MinusOne1024, + _ => throw new ArgumentOutOfRangeException(nameof(i), $"Parameter value {i} is incorrect"), + }; + } +} \ No newline at end of file