Skip to content

Add platform option for Lua 5.2 numeric text - #393

Merged
akeit0 merged 1 commit into
mainfrom
codex/platform-number-format
Oct 29, 2026
Merged

akeit0 merged 1 commit into
mainfrom
codex/platform-number-format

Conversation

@akeit0

@akeit0 akeit0 commented Oct 29, 2026

Copy link
Copy Markdown
Collaborator

Recreates #384 as an opt-in platform policy, preserving the existing managed default.

public enum LuaNumberFormat
{
    DotNet,
    Lua
}

using var state = LuaState.Create(LuaPlatform.Default with
{
    NumberFormat = LuaNumberFormat.Lua
});

DotNet preserves invariant managed numeric text. Lua uses Lua 5.2's default C-locale %.14g: 14 significant digits, lowercase exponents, signed zero, and portable signed inf/nan. For example, tostring(1/3) produces 0.33333333333333.

The option covers tostring and numeric __tostring results, %s/%q, concatenation, table.concat, all numeric gsub replacements, explicit-base tonumber numeric inputs, and numeric I/O (including accepted numeric input/output filenames). Coroutines inherit it independently of string mode. Explicit floating-point formats retain their requested finite precision; their special-value spellings follow the option. Public C# LuaValue.ToString(), arithmetic, NaN bits and parsing of numeric strings remain unchanged.

C Lua 5.2 details

  • luaconf.h defines the default LUA_NUMBER_FMT as %.14g. Numeric coercion and numeric I/O use it.
  • Explicit string formats call C sprintf; they do not all use 14 digits. %q quotes numeric text in Lua 5.2.
  • Special-value spelling is CRT-dependent. Windows can emit nan(ind)/nan(snan), as Microsoft documents. The Lua option normalizes these to signed nan, without serializing CRT classifier suffixes or changing the input bits. Existing portable finite %a formatting is retained; Windows CRT hexadecimal-format quirks are not emulated.
  • Fourteen-digit output can lose round-trip precision. tonumber(1e14,10) returns nil in Lua mode because its intermediate text is 1e+14; the managed default is preserved.

Validation

  • Release solution build: all four runtime targets, zero warnings/errors.
  • Full runtime suites pass on .NET 8 and .NET 10; all 73 generator tests pass.
  • All 58 policy cases pass on each framework, covering both policies, culture, rounding boundaries, subnormals, signed quiet/signaling NaNs, explicit formats, I/O in both string modes, numeric filenames and coroutine inheritance.
  • Native C Lua 5.2 comparison: 18,567 implicit conversions and 15 I/O cases, with zero differences after normalizing Windows NaN suffixes. Another 2,700 explicit-format comparisons identify the existing CRT-specific hexadecimal spelling/flag differences described above.
  • CSharpier and benchmark --verify pass.
  • Paired .NET 10 conversion benchmarks keep the managed default within about 4% of main, with unchanged allocations. The sampled Lua-mode conversions of 1/3 are about 4–16% faster with their shorter output; this is workload-specific.

Add LuaNumberFormat.DotNet and LuaNumberFormat.Lua on LuaPlatform, keeping
the existing invariant managed default and public LuaValue.ToString().
Route Lua numeric text through shared string/span formatting so the Lua
option uses C-locale %.14g and portable signed inf/nan spellings across
conversion, concatenation, replacements, explicit-base tonumber and I/O.
Explicit floating-point formats keep their requested finite precision.

Normalize Windows CRT NaN classifiers instead of making serialized text
host-dependent. Preserve NaN bits, sign, arithmetic and string parsing.
Document the policy and precision implications in both READMEs.

Validation: Release solution build passes without warnings for all runtime
targets. Full runtime suites pass on .NET 8/10, plus 73 generator tests;
all 58 numeric policy cases pass on both frameworks. CSharpier and benchmark
--verify pass. Native Lua 5.2 comparisons cover 18,567 implicit conversions
and 15 I/O cases with zero differences after NaN suffix normalization.
Explicit format comparisons identify existing Windows CRT hex-format
spelling/flag differences, which are intentionally not emulated.

Paired .NET 10 default conversion benchmarks remain within about 4% of main,
with unchanged allocations; Lua mode's shorter 1/3 output is about 4-16%
faster in the sampled conversion workloads.
@akeit0
akeit0 merged commit 92ff87b into main Oct 29, 2026
2 checks passed
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