Skip to main content
Version: 4.0 (next)

Format and parse metric numerals

Orientation

Use ToMetric for compact decimal magnitudes such as 123.5k, and FromMetric when an input follows Humanizer’s metric syntax. MetricNumeralFormats selects a symbol, SI prefix name, scale word, and optional spacing. Humanizer 4 can also preserve a fixed number of fractional digits. Numeric text follows CurrentCulture; automatic scale-word selection follows CurrentUICulture and reuses that locale's number-word data.

Example

The example pins en-US for numbers and de-DE for UI language, controls decimals, preserves a fixed decimal width, automatically selects a scale word, emits an SI prefix name, and parses a symbol:

Program.cs
using System.Globalization;
using Humanizer;

CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
CultureInfo.CurrentUICulture = CultureInfo.GetCultureInfo("de-DE");

var symbol = 123_456.ToMetric(decimals: 1);
var fixedWidth = 1_000d.ToMetric(
MetricNumeralFormats.KeepTrailingZeros,
decimals: 2);
var name = 1_000d.ToMetric(
MetricNumeralFormats.WithSpace | MetricNumeralFormats.UseName);
var scaleWord = 1.5E9.ToMetric(
MetricNumeralFormats.KeepTrailingZeros |
MetricNumeralFormats.WithSpace |
MetricNumeralFormats.UseScaleWord,
decimals: 2);
var parsed = "1.5k".FromMetric();

AssertEqual("123.5k", symbol);
AssertEqual("1.00k", fixedWidth);
AssertEqual("1 kilo", name);
AssertEqual("1.50 Milliarden", scaleWord);
AssertEqual(1500d, parsed);

Console.WriteLine($"{symbol}; {fixedWidth}; {name}; {scaleWord}; {parsed}");

static void AssertEqual<T>(T expected, T actual)
{
if (!EqualityComparer<T>.Default.Equals(expected, actual))
throw new InvalidOperationException($"Expected '{expected}', got '{actual}'.");
}

Select the representation

MetricNumeralFormats is a flags enum:

  • WithSpace inserts a space before the suffix.
  • UseName emits an SI prefix name such as kilo.
  • UseShortScaleWord emits words such as billion.
  • UseLongScaleWord emits the selected long-scale equivalent.
  • UseScaleWord emits the exact scale term authored for CurrentUICulture. It selects the locale-authored grammatical count form from the displayed, scaled numeral. Inverse scale words are used only for an authored singular form; other inverse counts keep the invariant SI symbol. When the locale has no standalone term for that power of 1000, it keeps the invariant SI symbol instead of falling back to an English word.
  • KeepTrailingZeros includes exactly the number of fractional digits requested by decimals.

Without KeepTrailingZeros, the nullable decimals argument is the maximum number of fractional digits: rounding applies at that limit and trailing zeros are omitted. Combine KeepTrailingZeros with a non-null decimals value when fixed-width output matters. The flag has no effect when decimals is null. It also applies to zero, negative values, values without a metric prefix, and values rounded into the next prefix. Leave both options unset to preserve the available precision in the default representation.

Use UseScaleWord for user-facing output that should follow the UI locale. Use UseShortScaleWord or UseLongScaleWord when an external format requires the existing English short- or long-scale vocabulary regardless of locale. CurrentCulture still controls the decimal separator and other numeric formatting in either case. KeepTrailingZeros composes with those representations and with WithSpace. When KeepTrailingZeros is active with a non-null decimals value, WithSpace still emits its trailing space even when no suffix is present, including for zero.

Parse supported forms

FromMetric accepts a numeric value followed by a supported SI symbol or prefix name, with optional whitespace. It returns double and throws ArgumentException for invalid syntax. Short- and long-scale words produced by ToMetric are display forms and do not round-trip through FromMetric.

Pitfall

Metric prefixes are powers of 1000. ByteSize uses a mixed unit contract: legacy KB through TB are binary multiples, PB and EB are decimal SI, and explicit IEC symbols such as KiB and PiB are binary. The supported metric exponent range stops before 10^27 and below 10^-27; out-of-range values throw. Because there is no culture parameter, scope CurrentCulture when parsing or exact numeric output matters, and scope CurrentUICulture when UseScaleWord must be deterministic.

Version notes

Metric conversion spans the documented corpus, but Humanizer 3 removed older boolean formatting overloads in favor of MetricNumeralFormats. UseScaleWord and KeepTrailingZeros are available in Humanizer 4. The executable uses the selected version's formatting API and runs against that package.