Skip to content

Commit 68a8757

Browse files
authored
Merge pull request #13 from crookseta/2.x
Merge 2.0.0
2 parents b57f185 + a151b38 commit 68a8757

File tree

73 files changed

+54608
-6762
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+54608
-6762
lines changed

README.md

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# MissingValues numeric library for .Net 7+
1+
# MissingValues numeric library for .Net 8+
22

3-
MissingValues is a C# numeric library for C# that introduces support for large integers and higher precision floating-point numbers. It supports .Net 7 Generic Math.
3+
MissingValues is a C# numeric library for C# that introduces support for large integers and higher precision floating-point numbers. It supports generic math.
44

55
## Features
66

@@ -29,49 +29,53 @@ Here is a chart comparing the existing binary integers to the MissingValues inte
2929

3030
**Example Usage**
3131

32-
using MissingValues; // namespace
33-
34-
// You can use the constructor:
35-
Int256 num1 = new Int256(0x8000_0000_0000_0000, 0x0000_0000_0000_0000, 0x0000_0000_0000_0000, 0x0000_0000_0000_0001);
36-
// You can use Parse():
37-
Int256 num2 = Int256.Parse("10000000000000000000000000000000000000000000000000000000000000000000000000000");
38-
// Or you can convert any other number type:
39-
Int256 num3 = long.MaxValue;
32+
```csharp
33+
using MissingValues; // namespace
4034
41-
// sum = -57896044618658097711785492504343953926634992332820282019728792003956564819967 + 10000000000000000000000000000000000000000000000000000000000000000000000000000 + 9223372036854775807
42-
Int256 sum = num1 + num2 + num3;
35+
// You can use the constructor:
36+
Int256 num1 = new Int256(0x8000_0000_0000_0000, 0x0000_0000_0000_0000, 0x0000_0000_0000_0000, 0x0000_0000_0000_0001);
37+
// You can use Parse():
38+
Int256 num2 = Int256.Parse("10000000000000000000000000000000000000000000000000000000000000000000000000000");
39+
// Or you can convert any other number type:
40+
Int256 num3 = long.MaxValue;
4341

44-
Console.WriteLine($"Sum: {sum}");
45-
46-
// Prints: -47896044618658097711785492504343953926634992332820282019719568631919710044160
42+
// sum = -57896044618658097711785492504343953926634992332820282019728792003956564819967 + 10000000000000000000000000000000000000000000000000000000000000000000000000000 + 9223372036854775807
43+
Int256 sum = num1 + num2 + num3;
4744

48-
### Quadruple-Precision Floating-Point Number
45+
Console.WriteLine($"Sum: {sum}");
4946

50-
The library introduces the `Quad` struct, representing a quadruple-precision floating-point number. Quadruple-precision offers higher precision than standard `double` or `float` types, making it suitable for applications requiring extensive precision in numerical calculations.
47+
// Prints: -47896044618658097711785492504343953926634992332820282019719568631919710044160
48+
```
49+
### Quadruple-Precision and Octuple-Precision Floating-Point Number
5150

52-
Here is a chart comparing the existing IEEE floating point numbers to `Quad`:
51+
The library introduces the `Quad` and `Octo` struct, representing a quadruple-precision floating-point and a octuple-precision floating-point number respectively.
52+
Quadruple-precision offers higher precision than standard `double` or `float` types, making it suitable for applications requiring extensive precision in numerical calculations.
53+
54+
Here is a chart comparing the existing IEEE floating point numbers to `Quad` and `Octo`:
5355

5456
| Name | Size | Significand Digits | Decimal Digits | Max Exponent | Min Exponent | Max Value | Min Value |
5557
|-------- |-------- |-------------------- |---------------- |-------------- |-------------- |----------- |------------ |
5658
| Half | 16 bits | 11 | 3.31 | 15 | -14 | ~65504 | ~-65500 |
5759
| Single | 32 bits | 24 | 7.22 | 127 | -126 | ~3.40e38 | ~-3.40e38 |
5860
| Double | 64 bits | 53 | 15.95 | 1023 | -1022 | ~1.80e308 | ~-1.79e308 |
5961
| Quad | 128 bits | 113 | 34.02 | 16383 | -16382 | ~1.19e4932 | ~-1.18e4932 |
62+
| Octo | 256 bits | 237 | 71.34 | 262143 | −262142 | ~1.61e78913 | ~-1.61e78913 |
6063

6164
**Example Usage**
65+
```csharp
66+
using MissingValues; // namespace
67+
68+
// You can use the constructor:
69+
Quad num1 = new Quad(sign: false, exp: 0x4004, sig: new UInt128(0x0000_9400_0000_0000, 0x0000_0000_0000_0000));
70+
// You can use Parse():
71+
Quad num2 = Quad.Parse("2e24");
72+
// Or you can convert any other number type:
73+
Quad num3 = 12.25d;
74+
75+
// sum = 50,5 + 2000000000000000000000000 + 12,25
76+
Quad sum = num1 + num2 + num3;
77+
78+
Console.WriteLine($"Sum: {sum}");
6279

63-
using MissingValues; // namespace
64-
65-
// You can use the constructor:
66-
Quad num1 = new Quad(sign: false, exp: 0x4004, sig: new UInt128(0x0000_9400_0000_0000, 0x0000_0000_0000_0000));
67-
// You can use Parse():
68-
Quad num2 = Quad.Parse("2e24");
69-
// Or you can convert any other number type:
70-
Quad num3 = 12.25d;
71-
72-
// sum = 50,5 + 2000000000000000000000000 + 12,25
73-
Quad sum = num1 + num2 + num3;
74-
75-
Console.WriteLine($"Sum: {sum}");
76-
77-
// Prints 2000000000000000000000062,75
80+
// Prints 2000000000000000000000062,75
81+
```

changelog/2.x.x/2.0.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# MissingValues 2.X.X
2+
### Breaking changes
3+
- .Net 7 is no longer supported. MissingValues will now only support .Net 8 and up.
4+
- Library is no longer CLS compliant.
5+
- Numeric constants (`One`, `Zero`, `MaxValue`, etc.) are now readonly variables instead of properties.
6+
7+
## 2.0.X Release Notes
8+
9+
### More number formats support
10+
`MissingValues.UInt256`, `MissingValues.Int256`, `MissingValues.UInt512`, `MissingValues.Int512`, `MissingValues.Quad` and `MissingValues.Octo`
11+
now support various numeric formats for their `ToString(string?, IFormatProvider?)` methods. the following formats are now supported:
12+
13+
#### Currency format
14+
```csharp
15+
Int512.MaxValue.ToString("C", NumberFormatInfo.InvariantInfo);
16+
// Returns: ¤6,703,903,964,971,298,549,787,012,499,102,923,063,739,682,910,296,196,688,861,780,721,860,882,015,036,773,488,400,937,149,083,451,713,845,015,929,093,243,025,426,876,941,405,973,284,973,216,824,503,042,047.00
17+
```
18+
19+
#### Scientific format
20+
```csharp
21+
Int512.MaxValue.ToString("E25", NumberFormatInfo.InvariantInfo);
22+
// Returns: 6.7039039649712985497870124991029230637396829102961966888617807218608820150367734884009371490834517138E+153
23+
```
24+
25+
#### Fixed format
26+
```csharp
27+
Int512.MinValue.ToString("F", NumberFormatInfo.InvariantInfo);
28+
// Returns: -6703903964971298549787012499102923063739682910296196688861780721860882015036773488400937149083451713845015929093243025426876941405973284973216824503042048.00
29+
```
30+
31+
#### Number format
32+
```csharp
33+
Int512.MinValue.ToString("N", NumberFormatInfo.InvariantInfo);
34+
// Returns: -6,703,903,964,971,298,549,787,012,499,102,923,063,739,682,910,296,196,688,861,780,721,860,882,015,036,773,488,400,937,149,083,451,713,845,015,929,093,243,025,426,876,941,405,973,284,973,216,824,503,042,048.00
35+
```
36+
37+
### Octuple-precision floating-point
38+
Introducing `MissingValues.Octo` struct, representing a octuple-precision floating-point. Octuple-precision offers higher precision than even `MissingValues.Quad`.
39+
40+
#### Construction
41+
Use the constructor the same way as `MissingValues.Quad`.
42+
```csharp
43+
// You can use the constructor:
44+
Octo num1 = new Octo(sign: false, exp: 0x40004, sig: new UInt256(0x0000_9400_0000_0000, 0x0000_0000_0000_0000, 0x0000_0000_0000_0000, 0x0000_0000_0000_0000));
45+
```
46+
47+
#### Generic math support
48+
`MissingValues.Octo` supports .Net 7s generic math, implementing `System.Numerics.IBinaryFloatingPointIeee754<T>`.
49+
```csharp
50+
static void Add<T>(T x, T y) where T : IAdditionOperators<T, T, T>
51+
{
52+
return x + y;
53+
}
54+
// You can use Octo:
55+
Octo z = Add(Octo.One, Octo.One);
56+
```
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
using BenchmarkDotNet.Attributes;
2+
using System.Numerics;
3+
4+
namespace MissingValues.Benchmarks;
5+
6+
[MinColumn, MaxColumn, MeanColumn, MedianColumn]
7+
[ShortRunJob]
8+
public class BigIntegerBenchmarks
9+
{
10+
[ParamsSource(nameof(ValuesSource))]
11+
public UInt128 Value { get; set; }
12+
BigInteger b256, b512;
13+
UInt256 u256;
14+
UInt512 u512;
15+
16+
[GlobalSetup]
17+
public void Setup()
18+
{
19+
u256 = (UInt256)(Int256.MaxValue / 2);
20+
u512 = (UInt512)(Int512.MaxValue / 2);
21+
22+
Span<byte> bytes = stackalloc byte[UInt256.Size];
23+
Int256.MaxValue.TryWriteLittleEndian(bytes);
24+
25+
b256 = new BigInteger(bytes, true);
26+
27+
bytes = stackalloc byte[UInt512.Size];
28+
Int512.MaxValue.TryWriteLittleEndian(bytes);
29+
30+
b512 = new BigInteger(bytes, true);
31+
}
32+
33+
[Benchmark]
34+
public BigInteger Add_BigInteger256()
35+
{
36+
return b256 + Value;
37+
}
38+
[Benchmark]
39+
public BigInteger Add_BigInteger512()
40+
{
41+
return b512 + Value;
42+
}
43+
[Benchmark]
44+
public UInt256 Add_UInt256()
45+
{
46+
return u256 + Value;
47+
}
48+
[Benchmark]
49+
public UInt512 Add_UInt512()
50+
{
51+
return u512 + Value;
52+
}
53+
54+
[Benchmark]
55+
public BigInteger Subtract_BigInteger256()
56+
{
57+
return b256 - Value;
58+
}
59+
[Benchmark]
60+
public BigInteger Subtract_BigInteger512()
61+
{
62+
return b512 - Value;
63+
}
64+
[Benchmark]
65+
public UInt256 Subtract_UInt256()
66+
{
67+
return u256 - Value;
68+
}
69+
[Benchmark]
70+
public UInt512 Subtract_UInt512()
71+
{
72+
return u512 - Value;
73+
}
74+
75+
[Benchmark]
76+
public BigInteger Multiply_BigInteger256()
77+
{
78+
return b256 * Value;
79+
}
80+
[Benchmark]
81+
public BigInteger Multiply_BigInteger512()
82+
{
83+
return b512 * Value;
84+
}
85+
[Benchmark]
86+
public UInt256 Multiply_UInt256()
87+
{
88+
return u256 * Value;
89+
}
90+
[Benchmark]
91+
public UInt512 Multiply_UInt512()
92+
{
93+
return u512 * Value;
94+
}
95+
96+
[Benchmark]
97+
public BigInteger Divide_BigInteger256()
98+
{
99+
return b256 / Value;
100+
}
101+
[Benchmark]
102+
public BigInteger Divide_BigInteger512()
103+
{
104+
return b512 / Value;
105+
}
106+
[Benchmark]
107+
public UInt256 Divide_UInt256()
108+
{
109+
return u256 / Value;
110+
}
111+
[Benchmark]
112+
public UInt512 Divide_UInt512()
113+
{
114+
return u512 / Value;
115+
}
116+
117+
[Benchmark]
118+
public BigInteger Remainder_BigInteger256()
119+
{
120+
return b256 % Value;
121+
}
122+
[Benchmark]
123+
public BigInteger Remainder_BigInteger512()
124+
{
125+
return b512 % Value;
126+
}
127+
[Benchmark]
128+
public UInt256 Remainder_UInt256()
129+
{
130+
return u256 % Value;
131+
}
132+
[Benchmark]
133+
public UInt512 Remainder_UInt512()
134+
{
135+
return u512 % Value;
136+
}
137+
138+
public IEnumerable<UInt128> ValuesSource()
139+
{
140+
yield return UInt128.Parse("1");
141+
yield return UInt128.Parse("2");
142+
yield return UInt128.Parse("10000000000000000000");
143+
yield return UInt128.Parse("100000000000000000000000000000000000000");
144+
}
145+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
using BenchmarkDotNet.Attributes;
2+
using MissingValues.Internals;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Globalization;
6+
using System.Linq;
7+
using System.Numerics;
8+
using System.Runtime.CompilerServices;
9+
using System.Text;
10+
using System.Threading.Tasks;
11+
12+
namespace MissingValues.Benchmarks
13+
{
14+
[MinColumn, MaxColumn, MeanColumn, MedianColumn]
15+
[GenericTypeArguments(typeof(int))]
16+
[GenericTypeArguments(typeof(long))]
17+
[GenericTypeArguments(typeof(Int128))]
18+
[GenericTypeArguments(typeof(Int256))]
19+
[GenericTypeArguments(typeof(Int512))]
20+
public class GenericIntegerBenchmarks<T>
21+
where T : INumber<T>
22+
{
23+
[Params(100, 10_000, 250_000, 750_000)]
24+
public int Length;
25+
26+
private T[] _v1, _v2;
27+
private T[] _destination;
28+
private string[] _toString;
29+
30+
[GlobalSetup]
31+
public void Setup()
32+
{
33+
_v1 = new T[Length];
34+
_v2 = new T[Length];
35+
36+
Span<byte> bytes = stackalloc byte[Unsafe.SizeOf<T>()];
37+
38+
for (int i = 0; i < Length; i++)
39+
{
40+
Random.Shared.NextBytes(bytes);
41+
_v1[i] = Unsafe.ReadUnaligned<T>(ref bytes[0]);
42+
}
43+
Random.Shared.GetItems(_v1, _v2.AsSpan());
44+
45+
_destination = new T[Length];
46+
_toString = new string[Length];
47+
}
48+
49+
[Benchmark]
50+
public T[] Add_Integer()
51+
{
52+
for (int i = 0; i < Length; i++)
53+
{
54+
_destination[i] = _v1[i] + _v2[i];
55+
}
56+
return _destination;
57+
}
58+
59+
[Benchmark]
60+
public T[] Subtract_Integer()
61+
{
62+
for (int i = 0; i < Length; i++)
63+
{
64+
_destination[i] = _v1[i] - _v2[i];
65+
}
66+
return _destination;
67+
}
68+
69+
[Benchmark]
70+
public T[] Multiply_Integer()
71+
{
72+
for (int i = 0; i < Length; i++)
73+
{
74+
_destination[i] = _v1[i] * _v2[i];
75+
}
76+
return _destination;
77+
}
78+
79+
[Benchmark]
80+
public T[] Divide_Integer()
81+
{
82+
for (int i = 0; i < Length; i++)
83+
{
84+
_destination[i] = _v1[i] / _v2[i];
85+
}
86+
return _destination;
87+
}
88+
89+
[Benchmark]
90+
public string[] ToString_Integer()
91+
{
92+
for (int i = 0; i < Length; i++)
93+
{
94+
_toString[i] = _v1[i].ToString()!;
95+
}
96+
return _toString;
97+
}
98+
}
99+
}

0 commit comments

Comments
 (0)