@@ -268,11 +268,11 @@ internal static partial class Number
268268 300 ;
269269#endif
270270 /// <summary>Lazily-populated cache of strings for uint values in the range [0, <see cref="SmallNumberCacheLength"/>).</summary>
271- private static readonly string [ ] s_smallNumberCache = new string [ SmallNumberCacheLength ] ;
271+ private static readonly string ? [ ] s_smallNumberCache = new string [ SmallNumberCacheLength ] ;
272272
273273 // Optimizations using "TwoDigits" inspired by:
274274 // https://engineering.fb.com/2013/03/15/developer-tools/three-optimization-tips-for-c/
275- private static readonly byte [ ] TwoDigitsCharsAsBytes =
275+ private static ReadOnlySpan < byte > TwoDigitsCharsAsBytes =>
276276 MemoryMarshal . AsBytes < char > ( "00010203040506070809" +
277277 "10111213141516171819" +
278278 "20212223242526272829" +
@@ -282,9 +282,9 @@ internal static partial class Number
282282 "60616263646566676869" +
283283 "70717273747576777879" +
284284 "80818283848586878889" +
285- "90919293949596979899" ) . ToArray ( ) ;
286- private static readonly byte [ ] TwoDigitsBytes =
287- ( "00010203040506070809"u8 +
285+ "90919293949596979899" ) ;
286+ private static ReadOnlySpan < byte > TwoDigitsBytes =>
287+ "00010203040506070809"u8 +
288288 "10111213141516171819"u8 +
289289 "20212223242526272829"u8 +
290290 "30313233343536373839"u8 +
@@ -293,7 +293,7 @@ internal static partial class Number
293293 "60616263646566676869"u8 +
294294 "70717273747576777879"u8 +
295295 "80818283848586878889"u8 +
296- "90919293949596979899"u8 ) . ToArray ( ) ;
296+ "90919293949596979899"u8 ;
297297
298298 public static unsafe string FormatDecimal ( decimal value , ReadOnlySpan < char > format , NumberFormatInfo info )
299299 {
@@ -387,9 +387,8 @@ private static int GetFloatingPointMaxDigitsAndPrecision(char fmt, ref int preci
387387
388388 int maxDigits = precision ;
389389
390- switch ( fmt )
390+ switch ( fmt | 0x20 )
391391 {
392- case 'C' :
393392 case 'c' :
394393 {
395394 // The currency format uses the precision specifier to indicate the number of
@@ -404,7 +403,6 @@ private static int GetFloatingPointMaxDigitsAndPrecision(char fmt, ref int preci
404403 break ;
405404 }
406405
407- case 'E' :
408406 case 'e' :
409407 {
410408 // The exponential format uses the precision specifier to indicate the number of
@@ -423,9 +421,7 @@ private static int GetFloatingPointMaxDigitsAndPrecision(char fmt, ref int preci
423421 break ;
424422 }
425423
426- case 'F' :
427424 case 'f' :
428- case 'N' :
429425 case 'n' :
430426 {
431427 // The fixed-point and number formats use the precision specifier to indicate the number
@@ -440,7 +436,6 @@ private static int GetFloatingPointMaxDigitsAndPrecision(char fmt, ref int preci
440436 break ;
441437 }
442438
443- case 'G' :
444439 case 'g' :
445440 {
446441 // The general format uses the precision specifier to indicate the number of significant
@@ -457,7 +452,6 @@ private static int GetFloatingPointMaxDigitsAndPrecision(char fmt, ref int preci
457452 break ;
458453 }
459454
460- case 'P' :
461455 case 'p' :
462456 {
463457 // The percent format uses the precision specifier to indicate the number of
@@ -476,7 +470,6 @@ private static int GetFloatingPointMaxDigitsAndPrecision(char fmt, ref int preci
476470 break ;
477471 }
478472
479- case 'R' :
480473 case 'r' :
481474 {
482475 // The roundtrip format ignores the precision specifier and always returns the shortest
@@ -1579,7 +1572,7 @@ internal static unsafe void WriteTwoDigits<TChar>(uint value, TChar* ptr) where
15791572
15801573 Unsafe . CopyBlockUnaligned (
15811574 ref * ( byte * ) ptr ,
1582- ref Unsafe . Add ( ref MemoryMarshal . GetArrayDataReference ( typeof ( TChar ) == typeof ( char ) ? TwoDigitsCharsAsBytes : TwoDigitsBytes ) , ( uint ) sizeof ( TChar ) * 2 * value ) ,
1575+ ref Unsafe . Add ( ref MemoryMarshal . GetReference ( typeof ( TChar ) == typeof ( char ) ? TwoDigitsCharsAsBytes : TwoDigitsBytes ) , ( uint ) sizeof ( TChar ) * 2 * value ) ,
15831576 ( uint ) sizeof ( TChar ) * 2 ) ;
15841577 }
15851578
@@ -1595,7 +1588,7 @@ internal static unsafe void WriteFourDigits<TChar>(uint value, TChar* ptr) where
15951588
15961589 ( value , uint remainder ) = Math. DivRem ( value , 100 ) ;
15971590
1598- ref byte charsArray = ref MemoryMarshal. GetArrayDataReference ( typeof ( TChar ) == typeof ( char ) ? TwoDigitsCharsAsBytes : TwoDigitsBytes ) ;
1591+ ref byte charsArray = ref MemoryMarshal. GetReference ( typeof ( TChar ) == typeof ( char ) ? TwoDigitsCharsAsBytes : TwoDigitsBytes ) ;
15991592
16001593 Unsafe. CopyBlockUnaligned (
16011594 ref * ( byte * ) ptr ,
@@ -1677,7 +1670,7 @@ internal static unsafe void WriteDigits<TChar>(uint value, TChar* ptr, int count
16771670 return bufferEnd;
16781671 }
16791672
1680- internal static unsafe string UInt32ToDecStr( uint value )
1673+ internal static string UInt32ToDecStr ( uint value )
16811674 {
16821675 // For small numbers, consult a lazily-populated cache.
16831676 if ( value < SmallNumberCacheLength )
@@ -2540,102 +2533,6 @@ private static unsafe bool TryUInt128ToDecStr<TChar>(UInt128 value, int digits,
25402533 return false;
25412534 }
25422535
2543- private static ulong ExtractFractionAndBiasedExponent ( double value , out int exponent)
2544- {
2545- ulong bits = BitConverter. DoubleToUInt64Bits( value ) ;
2546- ulong fraction = ( bits & 0xFFFFFFFFFFFFF ) ;
2547- exponent = ( ( int ) ( bits > > 52 ) & 0x7FF ) ;
2548-
2549- if ( exponent != 0 )
2550- {
2551- // For normalized value, according to https://en.wikipedia.org/wiki/Double-precision_floating-point_format
2552- // value = 1.fraction * 2^(exp - 1023)
2553- // = (1 + mantissa / 2^52) * 2^(exp - 1023)
2554- // = (2^52 + mantissa) * 2^(exp - 1023 - 52)
2555- //
2556- // So f = (2^52 + mantissa), e = exp - 1075;
2557-
2558- fraction |= ( 1UL << 52 ) ;
2559- exponent -= 1075 ;
2560- }
2561- else
2562- {
2563- // For denormalized value, according to https://en.wikipedia.org/wiki/Double-precision_floating-point_format
2564- // value = 0.fraction * 2^(1 - 1023)
2565- // = (mantissa / 2^52) * 2^(-1022)
2566- // = mantissa * 2^(-1022 - 52)
2567- // = mantissa * 2^(-1074)
2568- // So f = mantissa, e = -1074
2569- exponent = - 1074 ;
2570- }
2571-
2572- return fraction;
2573- }
2574-
2575- private static ushort ExtractFractionAndBiasedExponent( Half value , out int exponent)
2576- {
2577- ushort bits = BitConverter . HalfToUInt16Bits ( value ) ;
2578- ushort fraction = ( ushort ) ( bits & 0x3FF ) ;
2579- exponent = ( ( int ) ( bits >> 10 ) & 0x1F ) ;
2580-
2581- if ( exponent != 0 )
2582- {
2583- // For normalized value, according to https://en.wikipedia.org/wiki/Half-precision_floating-point_format
2584- // value = 1.fraction * 2^(exp - 15)
2585- // = (1 + mantissa / 2^10) * 2^(exp - 15)
2586- // = (2^10 + mantissa) * 2^(exp - 15 - 10)
2587- //
2588- // So f = (2^10 + mantissa), e = exp - 25;
2589-
2590- fraction |= ( ushort ) ( 1U << 10 ) ;
2591- exponent -= 25 ;
2592- }
2593- else
2594- {
2595- // For denormalized value, according to https://en.wikipedia.org/wiki/Half-precision_floating-point_format
2596- // value = 0.fraction * 2^(1 - 15)
2597- // = (mantissa / 2^10) * 2^(-14)
2598- // = mantissa * 2^(-14 - 10)
2599- // = mantissa * 2^(-24)
2600- // So f = mantissa, e = -24
2601- exponent = - 24 ;
2602- }
2603-
2604- return fraction;
2605- }
2606-
2607- private static uint ExtractFractionAndBiasedExponent( float value, out int exponent)
2608- {
2609- uint bits = BitConverter. SingleToUInt32Bits( value) ;
2610- uint fraction = ( bits & 0x7FFFFF ) ;
2611- exponent = ( ( int ) ( bits >> 23 ) & 0xFF ) ;
2612-
2613- if ( exponent != 0 )
2614- {
2615- // For normalized value, according to https://en.wikipedia.org/wiki/Single-precision_floating-point_format
2616- // value = 1.fraction * 2^(exp - 127)
2617- // = (1 + mantissa / 2^23) * 2^(exp - 127)
2618- // = (2^23 + mantissa) * 2^(exp - 127 - 23)
2619- //
2620- // So f = (2^23 + mantissa), e = exp - 150;
2621-
2622- fraction |= ( 1U << 23 ) ;
2623- exponent -= 150 ;
2624- }
2625- else
2626- {
2627- // For denormalized value, according to https://en.wikipedia.org/wiki/Single-precision_floating-point_format
2628- // value = 0.fraction * 2^(1 - 127)
2629- // = (mantissa / 2^23) * 2^(-126)
2630- // = mantissa * 2^(-126 - 23)
2631- // = mantissa * 2^(-149)
2632- // So f = mantissa, e = -149
2633- exponent = - 149 ;
2634- }
2635-
2636- return fraction;
2637- }
2638-
26392536 private static ulong ExtractFractionAndBiasedExponent < TNumber> ( TNumber value , out int exponent)
26402537 where TNumber : unmanaged , IBinaryFloatParseAndFormatInfo < TNumber >
26412538 {
0 commit comments