Skip to content

[patch] Fix conversion edge cases found in review - #72

Merged
matt-edmondson merged 1 commit into
mainfrom
fix-conversion-edge-cases
Sep 14, 2026
Merged

matt-edmondson merged 1 commit into
mainfrom
fix-conversion-edge-cases

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Summary

ktsu.PreciseNumber 2.0.0 and 2.0.1 shipped with these bugs, and this PR fixes them:

  • On .NET 7 and 8, converting a PreciseNumber with more than 1000 fraction digits to double, float, Half, or decimal returned 0. PreciseNumber.Parse("1." + new string('0', 1000) + "1") converted to 0 instead of 1.
  • double.MaxValue and double.MinValue converted to PreciseNumber and back came out as positive and negative infinity.
  • Converting a value whose exponent is int.MinValue threw OverflowException (to double and float) or ArgumentOutOfRangeException (to integer types) instead of returning 0.
  • TryParse("1e99999999999", null, out _) threw OverflowException instead of returning false.
  • Round and ReduceSignificance rounded wrong whenever they dropped two or more digits. 123.456.ToPreciseNumber().ReduceSignificance(3) gave 124, and 1.2345 rounded to two decimal places gave 1.24. This one predates 2.0 and turned up during the SignificantNumber migration.

The docs also claimed that arithmetic on values with small significands allocates nothing. That holds only when the operands and every intermediate and final significand fit in an int, so the README, CLAUDE.md, and the migration guide now say that.

Behavior changes to note

  • ToPreciseNumber() and CreateChecked from a double or float keep the shortest digits that round-trip instead of 16 or 8 significant digits. (0.1 + 0.2).ToPreciseNumber() is now 0.30000000000000004, and a result that routes through double, such as Exp(-1), carries a 17th digit when the double needs one.
  • Parse throws OverflowException for an exponent outside the range of int. That includes 1.5E-2147483648 and 10E2147483647, which used to wrap silently to a wrong value.
  • Round and ReduceSignificance return different results for inputs that drop two or more digits below half.

How

  • Conversions to binary floating point and decimal render normalized scientific notation (d.ddd…E±n), so any value within range of the destination has a small exponent. Every digit is still rendered. Truncating to the destination's precision was considered and rejected, because correct rounding can hinge on a nonzero digit far past the cut.
  • Floating point input is formatted with "R".
  • The Clinger fast paths use a range pattern instead of int.Abs(Exponent), and truncation widens the exponent to long before negating it.
  • TryParse catches OverflowException as well as FormatException. Parse uses checked arithmetic when it adjusts the exponent for the decimal point, and so does the constructor when it strips trailing zeros.
  • Round and ReduceSignificance divide by the power of ten and compare the exact remainder with half the divisor, rounding half away from zero. Divide already rounded that way and wasn't affected.

Risk and testing

The rounding fix and the 17-digit conversions change results that callers may have pinned. Three existing tests encoded the old behavior, and each now expects the exact value:

  • TestStaticRound expected 1.2345 to round to 1.24 and now expects 1.23.
  • TestReduceSignificance expected 12345 at three digits to have significand 124 and now expects 123.
  • TestExpWithNegativePower expected 1/e rebuilt at the result's precision and now expects 0.36787944117144233, the exact round trip of Math.Exp(-1).

New tests cover the following:

  • Conversions with 1000 to 1500 fraction digits, including cases where a digit past the halfway point decides the rounding.
  • Round trips of MaxValue, MinValue, and Epsilon for double, float, and Half.
  • An int.MinValue exponent converted to floating point, decimal, integer, and BigInteger destinations.
  • Out-of-range exponents in Parse and TryParse.
  • Rounding just below, at, and just above halfway, for positive and negative values, plus single-digit cases that pin the old behavior where it was already right.

All 260 tests pass on net10.0, and the library builds for net7.0, net8.0, net9.0, and net10.0 with no warnings. The long fraction bug only reproduces in the .NET 7 and 8 parsers, which the net10.0 test project can't reach. A file-based app built for net8.0 on runtime 8.0.31 returned 0 for 1.(1000 zeros)1 before the fix and 1 after, for all four destination types.

Known limitation

Formatting a value whose exponent is int.MinValue can still throw, because CountDecimalDigits and TryFormat negate the exponent. That's outside the conversion paths this PR fixes and is left for a follow-up.

🤖 Generated with Claude Code

https://claude.ai/code/session_01K5Bk9UjGdGUtC5C6qK5ZxD

Render normalized scientific notation when converting to double, float,
Half, and decimal. The .NET 7 and 8 parsers clamp an exponent above 1000
and still offset it by every digit before the point, so a value with more
than 1000 fraction digits converted to zero on those runtimes. Every digit
is still rendered, so rounding stays correct.

Format double and float input with the shortest round-trippable text
instead of 16 and 8 significant digits. double.MaxValue and MinValue no
longer convert back to infinity, and 0.3048 stays exactly 0.3048.

Handle an exponent of int.MinValue in every conversion. The fast paths
called int.Abs, which throws, and truncation negated the exponent, which
wraps. Such values now convert to zero.

Return false from TryParse for an exponent outside the range of int, and
throw OverflowException from Parse for it consistently, including when the
decimal point or stripped trailing zeros push the exponent out of range.

Round on the exact dropped digits in Round and ReduceSignificance. Adding
a run of fives rounded 123.456 to 124 at three significant digits and
1.2345 to 1.24 at two decimal places. This predates 2.0. Divide already
rounded exactly and is unchanged.

Narrow the allocation claim in the README, CLAUDE.md, and the migration
guide to operations whose operands and intermediate and final significands
fit in an int, and document the conversion and TryParse changes.

Claude-Session: https://claude.ai/code/session_01K5Bk9UjGdGUtC5C6qK5ZxD
@sonarqubecloud

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit d77ce99 into main Sep 14, 2026
13 checks passed
@matt-edmondson
matt-edmondson deleted the fix-conversion-edge-cases branch September 14, 2026 12:36

Copy link
Copy Markdown
Contributor Author

1.x → 2.x benchmarks, both sides on one machine

Run 34839905392 ran both versions back to back in a single job, so the two sets of timings are comparable — separate runs land on different CPUs and are not. Both sides report the same Intel Xeon Platinum 8370C, x86-64-v4.

  • 1.x = cd9a822 (main immediately before the value type merged)
  • 2.x = main as checked out at 11:46 UTC, which is b2427f0this is before [patch] Fix conversion edge cases found in review #72 merged, so the conversion and rounding fixes in this PR are not in these numbers.

Summary

88 benchmarks matched on method and parameters across 7 classes.

Count
Faster by more than 2% 57
Slower by more than 2% 15
Within ±2% 16
Allocation eliminated entirely 16

No benchmark allocates more than it did in 1.x — 50 rows allocate less, 38 are unchanged, none regressed. The 40-byte object header is gone from every value, which is what takes Negate, Sanitizing, Unsanitized, Round at 8 digits, Parse at 8 digits, and all five scalar conversions to zero.

Biggest wins are ToDouble (-79.6%), GetHashCode at 8 digits (-56.8%), Unsanitized construction (-54.0%), EqualsSameExponent (about -52% at every width), and ToInt32 (-47.8%).

Where 2.x is slower

Worth naming rather than burying:

  • Max is slower at all three widths (+23.1%, +16.8%, +84.4%) and CompareTo at all three (+15.9%, +15.6%, +4.9%). These are consistent across the parameter axis rather than one-off, so they look real.
  • Divide is +4.3% / +6.3% / +1.9%, matching the earlier, noisier CI numbers.
  • ReduceSignificance at 8 digits (+18.7%), Pow at power 2 (+12.7%), TryFormat at 8 digits (+10.7%).

One caveat on reading the Comparison table: those benchmarks run at 1–5 ns, close to the measurement floor, so a large percentage there is a sub-2 ns absolute difference. The 200-digit arithmetic is essentially flat (-3.1% to +1.9%), which is better than the earlier CI numbers suggested.

Full results

Arithmetic

Method Digits Mean 1.x Mean 2.x Δ Mean Alloc 1.x Alloc 2.x Δ Alloc
Add 8 65.76 ns 63.07 ns -4.1% 104 B 64 B -38.5%
Divide 8 227.46 ns 237.26 ns +4.3% 192 B 152 B -20.8%
Mod 8 69.38 ns 50.75 ns -26.9% 72 B 32 B -55.6%
Multiply 8 47.64 ns 44.25 ns -7.1% 72 B 32 B -55.6%
MultiplyWideExponentGap 8 47.39 ns 43.38 ns -8.5% 72 B 32 B -55.6%
Negate 8 19.54 ns 13.85 ns -29.1% 40 B - -100.0%
Squared 8 42.08 ns 37.06 ns -11.9% 72 B 32 B -55.6%
Subtract 8 64.19 ns 65.34 ns +1.8% 104 B 64 B -38.5%
Add 30 100.18 ns 93.36 ns -6.8% 120 B 80 B -33.3%
Divide 30 381.25 ns 405.16 ns +6.3% 240 B 200 B -16.7%
Mod 30 111.58 ns 107.25 ns -3.9% 120 B 80 B -33.3%
Multiply 30 106.42 ns 103.26 ns -3.0% 96 B 56 B -41.7%
MultiplyWideExponentGap 30 105.62 ns 101.63 ns -3.8% 96 B 56 B -41.7%
Negate 30 32.40 ns 30.11 ns -7.1% 40 B - -100.0%
Squared 30 100.79 ns 90.46 ns -10.2% 96 B 56 B -41.7%
Subtract 30 98.50 ns 92.74 ns -5.8% 120 B 80 B -33.3%
Add 200 238.92 ns 234.54 ns -1.8% 264 B 224 B -15.2%
Divide 200 1.65 μs 1.68 μs +1.9% 568 B 528 B -7.0%
Mod 200 260.60 ns 252.56 ns -3.1% 264 B 224 B -15.2%
Multiply 200 753.88 ns 744.56 ns -1.2% 232 B 192 B -17.2%
MultiplyWideExponentGap 200 750.87 ns 746.06 ns -0.6% 232 B 192 B -17.2%
Negate 200 126.45 ns 125.43 ns -0.8% 40 B - -100.0%
Squared 200 582.54 ns 582.93 ns +0.1% 232 B 192 B -17.2%
Subtract 200 239.77 ns 234.06 ns -2.4% 264 B 224 B -15.2%

Comparison

Method Digits Mean 1.x Mean 2.x Δ Mean Alloc 1.x Alloc 2.x Δ Alloc
CompareTo 8 1.65 ns 1.91 ns +15.9% - - 0.0%
EqualsDifferentDecade 8 2.55 ns 1.96 ns -23.3% - - 0.0%
EqualsDifferentExponent 8 2.60 ns 1.96 ns -24.5% - - 0.0%
EqualsSameExponent 8 6.19 ns 2.96 ns -52.1% - - 0.0%
GetHashCodeBenchmark 8 2.76 ns 1.19 ns -56.8% - - 0.0%
LessThan 8 2.03 ns 1.95 ns -4.1% - - 0.0%
Max 8 2.99 ns 3.68 ns +23.1% - - 0.0%
CompareTo 30 1.65 ns 1.91 ns +15.6% - - 0.0%
EqualsDifferentDecade 30 3.11 ns 1.96 ns -37.0% - - 0.0%
EqualsDifferentExponent 30 2.56 ns 1.96 ns -23.2% - - 0.0%
EqualsSameExponent 30 9.08 ns 4.36 ns -51.9% - - 0.0%
GetHashCodeBenchmark 30 12.61 ns 11.87 ns -5.8% - - 0.0%
LessThan 30 2.03 ns 1.94 ns -4.2% - - 0.0%
Max 30 2.98 ns 3.49 ns +16.8% - - 0.0%
CompareTo 200 1.83 ns 1.92 ns +4.9% - - 0.0%
EqualsDifferentDecade 200 2.61 ns 1.94 ns -25.5% - - 0.0%
EqualsDifferentExponent 200 2.44 ns 1.94 ns -20.2% - - 0.0%
EqualsSameExponent 200 9.47 ns 4.38 ns -53.7% - - 0.0%
GetHashCodeBenchmark 200 24.89 ns 23.91 ns -4.0% - - 0.0%
LessThan 200 1.95 ns 1.93 ns -0.8% - - 0.0%
Max 200 2.30 ns 4.24 ns +84.4% - - 0.0%

Construction

Method Digits Mean 1.x Mean 2.x Δ Mean Alloc 1.x Alloc 2.x Δ Alloc
Sanitizing 8 18.69 ns 12.98 ns -30.5% 40 B - -100.0%
SanitizingTrailingZeros 8 138.28 ns 130.77 ns -5.4% 104 B 64 B -38.5%
Unsanitized 8 12.21 ns 5.62 ns -54.0% 40 B - -100.0%
Sanitizing 30 38.31 ns 28.75 ns -25.0% 40 B - -100.0%
SanitizingTrailingZeros 30 465.96 ns 438.48 ns -5.9% 248 B 208 B -16.1%
Unsanitized 30 17.07 ns 12.37 ns -27.5% 40 B - -100.0%
Sanitizing 200 136.35 ns 116.62 ns -14.5% 40 B - -100.0%
SanitizingTrailingZeros 200 6.01 μs 5.97 μs -0.7% 1,000 B 960 B -4.0%
Unsanitized 200 16.98 ns 11.29 ns -33.5% 40 B - -100.0%

Conversion

Method Mean 1.x Mean 2.x Δ Mean Alloc 1.x Alloc 2.x Δ Alloc
FromDecimal 205.77 ns 191.79 ns -6.8% 40 B - -100.0%
FromDouble 314.97 ns 310.22 ns -1.5% 40 B - -100.0%
FromInt32 21.97 ns 16.12 ns -26.6% 40 B - -100.0%
FromInt64 40.25 ns 35.80 ns -11.1% 72 B 32 B -55.6%
FromSingle 259.59 ns 251.03 ns -3.3% 40 B - -100.0%
ToDouble 14.19 ns 2.90 ns -79.6% - - 0.0%
ToInt32 6.46 ns 3.38 ns -47.8% - - 0.0%

Pow

Method Power Mean 1.x Mean 2.x Δ Mean Alloc 1.x Alloc 2.x Δ Alloc
Pow 2 50.87 ns 57.33 ns +12.7% 72 B 32 B -55.6%
Pow 10 329.64 ns 321.78 ns -2.4% 344 B 184 B -46.5%
Pow 64 1.44 μs 1.43 μs -0.8% 800 B 560 B -30.0%

Rounding

Method Digits Mean 1.x Mean 2.x Δ Mean Alloc 1.x Alloc 2.x Δ Alloc
Clamp 8 4.94 ns 4.43 ns -10.2% - - 0.0%
ReduceSignificance 8 63.53 ns 75.44 ns +18.7% 40 B - -100.0%
Round 8 64.16 ns 58.95 ns -8.1% 40 B - -100.0%
Clamp 30 5.17 ns 4.70 ns -9.3% - - 0.0%
ReduceSignificance 30 164.44 ns 159.10 ns -3.2% 200 B 160 B -20.0%
Round 30 164.78 ns 157.52 ns -4.4% 200 B 160 B -20.0%
Clamp 200 5.43 ns 4.57 ns -15.8% - - 0.0%
ReduceSignificance 200 366.92 ns 350.69 ns -4.4% 488 B 448 B -8.2%
Round 200 365.40 ns 356.24 ns -2.5% 488 B 448 B -8.2%

Text

Method Digits Mean 1.x Mean 2.x Δ Mean Alloc 1.x Alloc 2.x Δ Alloc
Parse 8 128.32 ns 121.33 ns -5.4% 40 B - -100.0%
ToStringFractional 8 65.19 ns 54.28 ns -16.7% 40 B 40 B 0.0%
ToStringIntegral 8 60.01 ns 53.42 ns -11.0% 48 B 48 B 0.0%
ToStringSmallMagnitude 8 61.49 ns 63.61 ns +3.4% 64 B 64 B 0.0%
TryFormat 8 36.96 ns 40.90 ns +10.7% - - 0.0%
Parse 30 308.10 ns 294.12 ns -4.5% 80 B 40 B -50.0%
ToStringFractional 30 111.50 ns 116.23 ns +4.2% 88 B 88 B 0.0%
ToStringIntegral 30 105.56 ns 109.09 ns +3.3% 96 B 96 B 0.0%
ToStringSmallMagnitude 30 117.79 ns 118.19 ns +0.3% 112 B 112 B 0.0%
TryFormat 30 87.13 ns 88.02 ns +1.0% - - 0.0%
Parse 200 1.65 μs 1.60 μs -2.7% 152 B 112 B -26.3%
ToStringFractional 200 779.52 ns 788.17 ns +1.1% 424 B 424 B 0.0%
ToStringIntegral 200 774.66 ns 778.15 ns +0.5% 432 B 432 B 0.0%
ToStringSmallMagnitude 200 788.61 ns 814.34 ns +3.3% 448 B 448 B 0.0%
TryFormat 200 712.32 ns 711.41 ns -0.1% - - 0.0%

Generated by Claude Code

@matt-edmondson

Copy link
Copy Markdown
Contributor Author

Benchmarks: 1.x against the value type, on one machine

Both versions ran back to back in a single GitHub Actions job on an Intel Xeon Platinum 8370C (4 logical cores), with the default BenchmarkDotNet job. "Before" is cd9a822, the last commit before #70. "After" is main when the run started, which is #70 without the fixes from #72. Earlier numbers in this PR came from separate runs that landed on different CPUs, so treat this table as the reference.

  • Allocation falls by 40 B on every operation that returns a value. Negate, construction, and most conversions allocate nothing.
  • Arithmetic is flat to faster. Most 8 and 30 digit operations are 3 to 12% faster, Mod and Negate at 8 digits about 28% faster, and 200 digit results are within 3%. Divide is 2 to 6% slower.
  • Comparisons are mostly faster (equality about 50%), but Max is 17 to 84% slower and CompareTo 5 to 16% slower, which is worth a follow-up.
  • Conversions are faster, with ToDouble 80% and ToInt32 48% faster.
  • Regressions to check: ReduceSignificance at 8 digits is 19% slower and Pow with exponent 2 is 13% slower. [patch] Fix conversion edge cases found in review #72 rewrote the rounding in ReduceSignificance after this run, so its number may have moved.
Full table (88 benchmarks)
Class Method Parameter Before After Change Allocated before Allocated after
Arithmetic Add 8 65.76 ns 63.07 ns -4% 104 B 64 B
Arithmetic Subtract 8 64.19 ns 65.34 ns +2% 104 B 64 B
Arithmetic Multiply 8 47.64 ns 44.25 ns -7% 72 B 32 B
Arithmetic MultiplyWideExponentGap 8 47.39 ns 43.38 ns -8% 72 B 32 B
Arithmetic Divide 8 227.46 ns 237.26 ns +4% 192 B 152 B
Arithmetic Mod 8 69.38 ns 50.75 ns -27% 72 B 32 B
Arithmetic Negate 8 19.54 ns 13.85 ns -29% 40 B -
Arithmetic Squared 8 42.08 ns 37.06 ns -12% 72 B 32 B
Arithmetic Add 30 100.18 ns 93.36 ns -7% 120 B 80 B
Arithmetic Subtract 30 98.50 ns 92.74 ns -6% 120 B 80 B
Arithmetic Multiply 30 106.42 ns 103.26 ns -3% 96 B 56 B
Arithmetic MultiplyWideExponentGap 30 105.62 ns 101.63 ns -4% 96 B 56 B
Arithmetic Divide 30 381.25 ns 405.16 ns +6% 240 B 200 B
Arithmetic Mod 30 111.58 ns 107.25 ns -4% 120 B 80 B
Arithmetic Negate 30 32.40 ns 30.11 ns -7% 40 B -
Arithmetic Squared 30 100.79 ns 90.46 ns -10% 96 B 56 B
Arithmetic Add 200 238.92 ns 234.54 ns -2% 264 B 224 B
Arithmetic Subtract 200 239.77 ns 234.06 ns -2% 264 B 224 B
Arithmetic Multiply 200 753.88 ns 744.56 ns -1% 232 B 192 B
Arithmetic MultiplyWideExponentGap 200 750.87 ns 746.06 ns -1% 232 B 192 B
Arithmetic Divide 200 1,653.78 ns 1,684.76 ns +2% 568 B 528 B
Arithmetic Mod 200 260.60 ns 252.56 ns -3% 264 B 224 B
Arithmetic Negate 200 126.45 ns 125.43 ns -1% 40 B -
Arithmetic Squared 200 582.54 ns 582.93 ns 0% 232 B 192 B
Comparison EqualsSameExponent 8 6.192 ns 2.964 ns -52% - -
Comparison EqualsDifferentExponent 8 2.595 ns 1.958 ns -25% - -
Comparison EqualsDifferentDecade 8 2.553 ns 1.957 ns -23% - -
Comparison LessThan 8 2.031 ns 1.948 ns -4% - -
Comparison CompareTo 8 1.645 ns 1.906 ns +16% - -
Comparison Max 8 2.991 ns 3.681 ns +23% - -
Comparison GetHashCodeBenchmark 8 2.756 ns 1.191 ns -57% - -
Comparison EqualsSameExponent 30 9.079 ns 4.363 ns -52% - -
Comparison EqualsDifferentExponent 30 2.558 ns 1.964 ns -23% - -
Comparison EqualsDifferentDecade 30 3.113 ns 1.960 ns -37% - -
Comparison LessThan 30 2.028 ns 1.942 ns -4% - -
Comparison CompareTo 30 1.650 ns 1.907 ns +16% - -
Comparison Max 30 2.985 ns 3.486 ns +17% - -
Comparison GetHashCodeBenchmark 30 12.606 ns 11.872 ns -6% - -
Comparison EqualsSameExponent 200 9.473 ns 4.385 ns -54% - -
Comparison EqualsDifferentExponent 200 2.437 ns 1.944 ns -20% - -
Comparison EqualsDifferentDecade 200 2.609 ns 1.944 ns -25% - -
Comparison LessThan 200 1.945 ns 1.929 ns -1% - -
Comparison CompareTo 200 1.834 ns 1.923 ns +5% - -
Comparison Max 200 2.301 ns 4.244 ns +84% - -
Comparison GetHashCodeBenchmark 200 24.893 ns 23.908 ns -4% - -
Construction Sanitizing 8 18.69 ns 12.984 ns -31% 40 B -
Construction SanitizingTrailingZeros 8 138.28 ns 130.773 ns -5% 104 B 64 B
Construction Unsanitized 8 12.21 ns 5.617 ns -54% 40 B -
Construction Sanitizing 30 38.31 ns 28.745 ns -25% 40 B -
Construction SanitizingTrailingZeros 30 465.96 ns 438.478 ns -6% 248 B 208 B
Construction Unsanitized 30 17.07 ns 12.374 ns -28% 40 B -
Construction Sanitizing 200 136.35 ns 116.619 ns -14% 40 B -
Construction SanitizingTrailingZeros 200 6,008.79 ns 5,965.416 ns -1% 1000 B 960 B
Construction Unsanitized 200 16.98 ns 11.288 ns -34% 40 B -
Conversion FromInt32 21.971 ns 16.120 ns -27% 40 B -
Conversion FromInt64 40.249 ns 35.798 ns -11% 72 B 32 B
Conversion FromDouble 314.971 ns 310.220 ns -2% 40 B -
Conversion FromSingle 259.588 ns 251.032 ns -3% 40 B -
Conversion FromDecimal 205.774 ns 191.793 ns -7% 40 B -
Conversion ToDouble 14.186 ns 2.897 ns -80% - -
Conversion ToInt32 6.461 ns 3.375 ns -48% - -
Pow Pow 2 50.87 ns 57.33 ns +13% 72 B 32 B
Pow Pow 10 329.64 ns 321.78 ns -2% 344 B 184 B
Pow Pow 64 1,437.81 ns 1,426.61 ns -1% 800 B 560 B
Rounding Round 8 64.160 ns 58.953 ns -8% 40 B -
Rounding ReduceSignificance 8 63.528 ns 75.437 ns +19% 40 B -
Rounding Clamp 8 4.937 ns 4.431 ns -10% - -
Rounding Round 30 164.775 ns 157.524 ns -4% 200 B 160 B
Rounding ReduceSignificance 30 164.440 ns 159.101 ns -3% 200 B 160 B
Rounding Clamp 30 5.174 ns 4.695 ns -9% - -
Rounding Round 200 365.404 ns 356.241 ns -3% 488 B 448 B
Rounding ReduceSignificance 200 366.921 ns 350.694 ns -4% 488 B 448 B
Rounding Clamp 200 5.432 ns 4.574 ns -16% - -
Text ToStringIntegral 8 60.01 ns 53.42 ns -11% 48 B 48 B
Text ToStringFractional 8 65.19 ns 54.28 ns -17% 40 B 40 B
Text ToStringSmallMagnitude 8 61.49 ns 63.61 ns +3% 64 B 64 B
Text TryFormat 8 36.96 ns 40.90 ns +11% - -
Text Parse 8 128.32 ns 121.33 ns -5% 40 B -
Text ToStringIntegral 30 105.56 ns 109.09 ns +3% 96 B 96 B
Text ToStringFractional 30 111.50 ns 116.23 ns +4% 88 B 88 B
Text ToStringSmallMagnitude 30 117.79 ns 118.19 ns 0% 112 B 112 B
Text TryFormat 30 87.13 ns 88.02 ns +1% - -
Text Parse 30 308.10 ns 294.12 ns -5% 80 B 40 B
Text ToStringIntegral 200 774.66 ns 778.15 ns 0% 432 B 432 B
Text ToStringFractional 200 779.52 ns 788.17 ns +1% 424 B 424 B
Text ToStringSmallMagnitude 200 788.61 ns 814.34 ns +3% 448 B 448 B
Text TryFormat 200 712.32 ns 711.41 ns 0% - -
Text Parse 200 1,649.16 ns 1,604.59 ns -3% 152 B 112 B

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant