forked from dotnet/runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTotalOrderIeee754ComparerTests.cs
378 lines (339 loc) · 22.6 KB
/
TotalOrderIeee754ComparerTests.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
// 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 System.Globalization;
using System.Numerics;
using System.Runtime.InteropServices;
using Xunit;
namespace System.Runtime.Tests
{
public sealed class TotalOrderIeee754ComparerTests
{
public static IEnumerable<object[]> SingleTestData
{
get
{
yield return new object[] { 0.0f, 0.0f, 0 };
yield return new object[] { -0.0f, -0.0f, 0 };
yield return new object[] { 0.0f, -0.0f, 1 };
yield return new object[] { -0.0f, 0.0f, -1 };
yield return new object[] { 0.0f, 1.0f, -1 };
yield return new object[] { float.PositiveInfinity, 1.0f, 1 };
yield return new object[] { BitConverter.UInt32BitsToSingle(0xFFC00000), float.NegativeInfinity, -1 };
yield return new object[] { BitConverter.UInt32BitsToSingle(0xFFC00000), -1.0f, -1 };
yield return new object[] { BitConverter.UInt32BitsToSingle(0x7FC00000), 1.0f, 1 };
yield return new object[] { BitConverter.UInt32BitsToSingle(0x7FC00000), float.PositiveInfinity, 1 };
yield return new object[] { float.NaN, float.NaN, 0 };
yield return new object[] { BitConverter.UInt32BitsToSingle(0xFFC00000), BitConverter.UInt32BitsToSingle(0x7FC00000), -1 };
yield return new object[] { BitConverter.UInt32BitsToSingle(0x7FC00000), BitConverter.UInt32BitsToSingle(0x7FC00001), -1 }; // implementation defined, not part of IEEE 754 totalOrder
}
}
[Theory]
[MemberData(nameof(SingleTestData))]
public void TotalOrderTestSingle(float x, float y, int result)
{
var comparer = new TotalOrderIeee754Comparer<float>();
Assert.Equal(result, Math.Sign(comparer.Compare(x, y)));
}
public static IEnumerable<object[]> DoubleTestData
{
get
{
yield return new object[] { 0.0, 0.0, 0 };
yield return new object[] { -0.0, -0.0, 0 };
yield return new object[] { 0.0, -0.0, 1 };
yield return new object[] { -0.0, 0.0, -1 };
yield return new object[] { 0.0, 1.0, -1 };
yield return new object[] { double.PositiveInfinity, 1.0, 1 };
yield return new object[] { BitConverter.UInt64BitsToDouble(0xFFF80000_00000000), double.NegativeInfinity, -1 };
yield return new object[] { BitConverter.UInt64BitsToDouble(0xFFF80000_00000000), -1.0, -1 };
yield return new object[] { BitConverter.UInt64BitsToDouble(0x7FF80000_00000000), 1.0, 1 };
yield return new object[] { BitConverter.UInt64BitsToDouble(0x7FF80000_00000000), double.PositiveInfinity, 1 };
yield return new object[] { double.NaN, double.NaN, 0 };
yield return new object[] { BitConverter.UInt64BitsToDouble(0xFFF80000_00000000), BitConverter.UInt64BitsToDouble(0x7FF80000_00000000), -1 };
yield return new object[] { BitConverter.UInt64BitsToDouble(0x7FF80000_00000000), BitConverter.UInt64BitsToDouble(0x7FF80000_00000001), -1 }; // implementation defined, not part of IEEE 754 totalOrder
}
}
[Theory]
[MemberData(nameof(DoubleTestData))]
public void TotalOrderTestDouble(double x, double y, int result)
{
var comparer = new TotalOrderIeee754Comparer<double>();
Assert.Equal(result, Math.Sign(comparer.Compare(x, y)));
}
public static IEnumerable<object[]> HalfTestData
{
get
{
yield return new object[] { (Half)0.0, (Half)0.0, 0 };
yield return new object[] { (Half)(-0.0), (Half)(-0.0), 0 };
yield return new object[] { (Half)0.0, (Half)(-0.0), 1 };
yield return new object[] { (Half)(-0.0), (Half)0.0, -1 };
yield return new object[] { (Half)0.0, (Half)1.0, -1 };
yield return new object[] { Half.PositiveInfinity, (Half)1.0, 1 };
yield return new object[] { BitConverter.UInt16BitsToHalf(0xFE00), Half.NegativeInfinity, -1 };
yield return new object[] { BitConverter.UInt16BitsToHalf(0xFE00), (Half)(-1.0), -1 };
yield return new object[] { BitConverter.UInt16BitsToHalf(0x7E00), (Half)1.0, 1 };
yield return new object[] { BitConverter.UInt16BitsToHalf(0x7E00), Half.PositiveInfinity, 1 };
yield return new object[] { Half.NaN, Half.NaN, 0 };
yield return new object[] { BitConverter.UInt16BitsToHalf(0xFE00), BitConverter.UInt16BitsToHalf(0x7E00), -1 };
yield return new object[] { BitConverter.UInt16BitsToHalf(0x7E00), BitConverter.UInt16BitsToHalf(0x7E01), -1 }; // implementation defined, not part of IEEE 754 totalOrder
}
}
[Theory]
[MemberData(nameof(HalfTestData))]
public void TotalOrderTestHalf(Half x, Half y, int result)
{
var comparer = new TotalOrderIeee754Comparer<Half>();
Assert.Equal(result, Math.Sign(comparer.Compare(x, y)));
}
public static IEnumerable<object[]> NFloatTestData
{
get
{
yield return new object[] { 0.0f, 0.0f, 0 };
yield return new object[] { -0.0f, -0.0f, 0 };
yield return new object[] { 0.0f, -0.0f, 1 };
yield return new object[] { -0.0f, 0.0f, -1 };
yield return new object[] { 0.0f, 1.0f, -1 };
yield return new object[] { NFloat.PositiveInfinity, 1.0f, 1 };
yield return new object[] { NFloat.NaN, NFloat.NaN, 0 };
if (Environment.Is64BitProcess)
{
yield return new object[] { BitConverter.UInt64BitsToDouble(0x7FF80000_00000000), 1.0d, 1 };
yield return new object[] { BitConverter.UInt64BitsToDouble(0x7FF80000_00000000), NFloat.PositiveInfinity, 1 };
yield return new object[] { BitConverter.UInt64BitsToDouble(0xFFF80000_00000000), NFloat.NegativeInfinity, -1 };
yield return new object[] { BitConverter.UInt64BitsToDouble(0xFFF80000_00000000), -1.0d, -1 };
yield return new object[] { BitConverter.UInt64BitsToDouble(0xFFF80000_00000000), BitConverter.UInt64BitsToDouble(0x7FF80000_00000000), -1 };
yield return new object[] { BitConverter.UInt64BitsToDouble(0x7FF80000_00000000), BitConverter.UInt64BitsToDouble(0x7FF80000_00000001), -1 }; // implementation defined, not part of IEEE 754 totalOrder
}
else
{
yield return new object[] { BitConverter.UInt32BitsToSingle(0x7FC00000), 1.0f, 1 };
yield return new object[] { BitConverter.UInt32BitsToSingle(0x7FC00000), NFloat.PositiveInfinity, 1 };
yield return new object[] { BitConverter.UInt32BitsToSingle(0xFFC00000), NFloat.NegativeInfinity, -1 };
yield return new object[] { BitConverter.UInt32BitsToSingle(0xFFC00000), -1.0f, -1 };
yield return new object[] { BitConverter.UInt32BitsToSingle(0xFFC00000), BitConverter.UInt32BitsToSingle(0x7FC00000), -1 };
yield return new object[] { BitConverter.UInt32BitsToSingle(0x7FC00000), BitConverter.UInt32BitsToSingle(0x7FC00001), -1 }; // implementation defined, not part of IEEE 754 totalOrder
}
}
}
[Theory]
[MemberData(nameof(NFloatTestData))]
public void TotalOrderTestNFloat(NFloat x, NFloat y, int result)
{
var comparer = new TotalOrderIeee754Comparer<NFloat>();
Assert.Equal(result, Math.Sign(comparer.Compare(x, y)));
}
[Theory]
[InlineData(-1)]
[InlineData(int.MinValue)]
public void TotalOrderTestInvalidSignificand(int significandByteCount)
{
var comparer = new TotalOrderIeee754Comparer<StubFloatingPointIeee754>();
StubFloatingPointIeee754 xy = new StubFloatingPointIeee754(1, significandByteCount);
Assert.Throws<OverflowException>(() => comparer.Compare(xy, xy));
}
private readonly struct StubFloatingPointIeee754 : IFloatingPointIeee754<StubFloatingPointIeee754>
{
private readonly int _significandBitLength;
private readonly int _significandByteCount;
public StubFloatingPointIeee754(int significandBitLength, int significandByteCount)
{
_significandBitLength = significandBitLength;
_significandByteCount = significandByteCount;
}
public static StubFloatingPointIeee754 Epsilon => default;
public static StubFloatingPointIeee754 NaN => default;
public static StubFloatingPointIeee754 NegativeInfinity => default;
public static StubFloatingPointIeee754 NegativeZero => default;
public static StubFloatingPointIeee754 PositiveInfinity => default;
public static StubFloatingPointIeee754 NegativeOne => default;
public static StubFloatingPointIeee754 E => default;
public static StubFloatingPointIeee754 Pi => default;
public static StubFloatingPointIeee754 Tau => default;
public static StubFloatingPointIeee754 One => default;
public static int Radix => default;
public static StubFloatingPointIeee754 Zero => default;
public static StubFloatingPointIeee754 AdditiveIdentity => default;
public static StubFloatingPointIeee754 MultiplicativeIdentity => default;
public static StubFloatingPointIeee754 Abs(StubFloatingPointIeee754 value) => default;
public static StubFloatingPointIeee754 Acos(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 Acosh(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 AcosPi(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 Asin(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 Asinh(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 AsinPi(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 Atan(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 Atan2(StubFloatingPointIeee754 y, StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 Atan2Pi(StubFloatingPointIeee754 y, StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 Atanh(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 AtanPi(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 BitDecrement(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 BitIncrement(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 Cbrt(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 Cos(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 Cosh(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 CosPi(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 Exp(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 Exp10(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 Exp2(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 FusedMultiplyAdd(StubFloatingPointIeee754 left, StubFloatingPointIeee754 right, StubFloatingPointIeee754 addend) => default;
public static StubFloatingPointIeee754 Hypot(StubFloatingPointIeee754 x, StubFloatingPointIeee754 y) => default;
public static StubFloatingPointIeee754 Ieee754Remainder(StubFloatingPointIeee754 left, StubFloatingPointIeee754 right) => default;
public static int ILogB(StubFloatingPointIeee754 x) => default;
public static bool IsCanonical(StubFloatingPointIeee754 value) => true;
public static bool IsComplexNumber(StubFloatingPointIeee754 value) => false;
public static bool IsEvenInteger(StubFloatingPointIeee754 value) => false;
public static bool IsFinite(StubFloatingPointIeee754 value) => false;
public static bool IsImaginaryNumber(StubFloatingPointIeee754 value) => false;
public static bool IsInfinity(StubFloatingPointIeee754 value) => false;
public static bool IsInteger(StubFloatingPointIeee754 value) => false;
public static bool IsNaN(StubFloatingPointIeee754 value) => true;
public static bool IsNegative(StubFloatingPointIeee754 value) => false;
public static bool IsNegativeInfinity(StubFloatingPointIeee754 value) => false;
public static bool IsNormal(StubFloatingPointIeee754 value) => false;
public static bool IsOddInteger(StubFloatingPointIeee754 value) => false;
public static bool IsPositive(StubFloatingPointIeee754 value) => false;
public static bool IsPositiveInfinity(StubFloatingPointIeee754 value) => false;
public static bool IsRealNumber(StubFloatingPointIeee754 value) => false;
public static bool IsSubnormal(StubFloatingPointIeee754 value) => false;
public static bool IsZero(StubFloatingPointIeee754 value) => false;
public static StubFloatingPointIeee754 Log(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 Log(StubFloatingPointIeee754 x, StubFloatingPointIeee754 newBase) => default;
public static StubFloatingPointIeee754 Log10(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 Log2(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 MaxMagnitude(StubFloatingPointIeee754 x, StubFloatingPointIeee754 y) => default;
public static StubFloatingPointIeee754 MaxMagnitudeNumber(StubFloatingPointIeee754 x, StubFloatingPointIeee754 y) => default;
public static StubFloatingPointIeee754 MinMagnitude(StubFloatingPointIeee754 x, StubFloatingPointIeee754 y) => default;
public static StubFloatingPointIeee754 MinMagnitudeNumber(StubFloatingPointIeee754 x, StubFloatingPointIeee754 y) => default;
public static StubFloatingPointIeee754 Parse(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider? provider) => default;
public static StubFloatingPointIeee754 Parse(string s, NumberStyles style, IFormatProvider? provider) => default;
public static StubFloatingPointIeee754 Parse(ReadOnlySpan<char> s, IFormatProvider? provider) => default;
public static StubFloatingPointIeee754 Parse(string s, IFormatProvider? provider) => default;
public static StubFloatingPointIeee754 Pow(StubFloatingPointIeee754 x, StubFloatingPointIeee754 y) => default;
public static StubFloatingPointIeee754 RootN(StubFloatingPointIeee754 x, int n) => default;
public static StubFloatingPointIeee754 Round(StubFloatingPointIeee754 x, int digits, MidpointRounding mode) => default;
public static StubFloatingPointIeee754 ScaleB(StubFloatingPointIeee754 x, int n) => default;
public static StubFloatingPointIeee754 Sin(StubFloatingPointIeee754 x) => default;
public static (StubFloatingPointIeee754 Sin, StubFloatingPointIeee754 Cos) SinCos(StubFloatingPointIeee754 x) => default;
public static (StubFloatingPointIeee754 SinPi, StubFloatingPointIeee754 CosPi) SinCosPi(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 Sinh(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 SinPi(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 Sqrt(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 Tan(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 Tanh(StubFloatingPointIeee754 x) => default;
public static StubFloatingPointIeee754 TanPi(StubFloatingPointIeee754 x) => default;
public static bool TryParse(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider? provider, out StubFloatingPointIeee754 result)
{
result = default;
return false;
}
public static bool TryParse(string? s, NumberStyles style, IFormatProvider? provider, out StubFloatingPointIeee754 result)
{
result = default;
return false;
}
public static bool TryParse(ReadOnlySpan<char> s, IFormatProvider? provider, out StubFloatingPointIeee754 result)
{
result = default;
return false;
}
public static bool TryParse(string? s, IFormatProvider? provider, out StubFloatingPointIeee754 result)
{
result = default;
return false;
}
static bool INumberBase<StubFloatingPointIeee754>.TryConvertFromChecked<TOther>(TOther value, out StubFloatingPointIeee754 result)
{
result = default;
return false;
}
static bool INumberBase<StubFloatingPointIeee754>.TryConvertFromSaturating<TOther>(TOther value, out StubFloatingPointIeee754 result)
{
result = default;
return false;
}
static bool INumberBase<StubFloatingPointIeee754>.TryConvertFromTruncating<TOther>(TOther value, out StubFloatingPointIeee754 result)
{
result = default;
return false;
}
static bool INumberBase<StubFloatingPointIeee754>.TryConvertToChecked<TOther>(StubFloatingPointIeee754 value, out TOther result)
{
result = default;
return false;
}
static bool INumberBase<StubFloatingPointIeee754>.TryConvertToSaturating<TOther>(StubFloatingPointIeee754 value, out TOther result)
{
result = default;
return false;
}
static bool INumberBase<StubFloatingPointIeee754>.TryConvertToTruncating<TOther>(StubFloatingPointIeee754 value, out TOther result)
{
result = default;
return false;
}
public int CompareTo(object? obj) => 1;
public int CompareTo(StubFloatingPointIeee754 other) => 1;
public bool Equals(StubFloatingPointIeee754 other) => false;
public int GetExponentByteCount() => 0;
public int GetExponentShortestBitLength() => 0;
public int GetSignificandBitLength() => _significandBitLength;
public int GetSignificandByteCount() => _significandByteCount;
public string ToString(string? format, IFormatProvider? formatProvider) => string.Empty;
public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider? provider)
{
charsWritten = 0;
return false;
}
public bool TryWriteExponentBigEndian(Span<byte> destination, out int bytesWritten)
{
bytesWritten = 0;
return false;
}
public bool TryWriteExponentLittleEndian(Span<byte> destination, out int bytesWritten)
{
bytesWritten = 0;
return false;
}
public bool TryWriteSignificandBigEndian(Span<byte> destination, out int bytesWritten)
{
if (destination.Length >= _significandByteCount)
{
bytesWritten = _significandByteCount;
return true;
}
bytesWritten = 0;
return false;
}
public bool TryWriteSignificandLittleEndian(Span<byte> destination, out int bytesWritten)
{
if (destination.Length >= _significandByteCount)
{
bytesWritten = _significandByteCount;
return true;
}
bytesWritten = 0;
return false;
}
public override bool Equals(object o) => false;
public override int GetHashCode() => 0;
public static StubFloatingPointIeee754 operator +(StubFloatingPointIeee754 value) => default;
public static StubFloatingPointIeee754 operator +(StubFloatingPointIeee754 left, StubFloatingPointIeee754 right) => default;
public static StubFloatingPointIeee754 operator -(StubFloatingPointIeee754 value) => default;
public static StubFloatingPointIeee754 operator -(StubFloatingPointIeee754 left, StubFloatingPointIeee754 right) => default;
public static StubFloatingPointIeee754 operator ++(StubFloatingPointIeee754 value) => default;
public static StubFloatingPointIeee754 operator --(StubFloatingPointIeee754 value) => default;
public static StubFloatingPointIeee754 operator *(StubFloatingPointIeee754 left, StubFloatingPointIeee754 right) => default;
public static StubFloatingPointIeee754 operator /(StubFloatingPointIeee754 left, StubFloatingPointIeee754 right) => default;
public static StubFloatingPointIeee754 operator %(StubFloatingPointIeee754 left, StubFloatingPointIeee754 right) => default;
public static bool operator ==(StubFloatingPointIeee754 left, StubFloatingPointIeee754 right) => false;
public static bool operator !=(StubFloatingPointIeee754 left, StubFloatingPointIeee754 right) => false;
public static bool operator <(StubFloatingPointIeee754 left, StubFloatingPointIeee754 right) => false;
public static bool operator >(StubFloatingPointIeee754 left, StubFloatingPointIeee754 right) => false;
public static bool operator <=(StubFloatingPointIeee754 left, StubFloatingPointIeee754 right) => false;
public static bool operator >=(StubFloatingPointIeee754 left, StubFloatingPointIeee754 right) => false;
}
}
}