From 3af41a1290e9db0feb2fcec9d860942ef34eba64 Mon Sep 17 00:00:00 2001 From: Jay Hemnani <193022578+jayhemnani9910@users.noreply.github.com> Date: Mon, 26 Oct 2026 15:10:52 +0530 Subject: [PATCH] interpreter: print integral numbers as integers A float went through the shortest round-trip formatter, so integral values from 1e16 up came out in exponent form (print 2^64 gave 1.8446744073709552e+19) and -0 printed as -0. POSIX converts an integer value as if by %d, and gawk prints 18446744073709551616 and 0. Write finite integral values with all their digits. --- interpreter/src/vm/types.rs | 6 ++++++ tests/by-util/test_awk.rs | 15 +++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/interpreter/src/vm/types.rs b/interpreter/src/vm/types.rs index 19cf257..df210b4 100644 --- a/interpreter/src/vm/types.rs +++ b/interpreter/src/vm/types.rs @@ -376,6 +376,12 @@ impl<'a> AwkValue<'a> { } match self { // TODO: NaN and infinities. + // An integral value is written as an integer, as by "%d" (POSIX), + // so 2^64 and 1e16 keep all their digits and -0 is "0". + Self::Float(f) if f.0.is_finite() && f.0.fract() == 0.0 => { + let n = if f.0 == 0.0 { 0.0 } else { f.0 }; + out.extend_from_slice(format!("{n:.0}").as_bytes()); + } Self::Float(f) => { let mut buf = zmij::Buffer::new(); let s = buf.format(f.0); diff --git a/tests/by-util/test_awk.rs b/tests/by-util/test_awk.rs index 9819842..10a115c 100644 --- a/tests/by-util/test_awk.rs +++ b/tests/by-util/test_awk.rs @@ -1005,3 +1005,18 @@ fn test_referencing_an_element_creates_it() { .succeeds() .stdout_only("1 1 2 0\n"); } + +#[test] +fn integral_numbers_print_as_integers() { + ucmd() + .arg("BEGIN { print 2^64, 1e16, -1e16, -0; x = 1e16 \"\"; print x }") + .succeeds() + .stdout_only( + "18446744073709551616 10000000000000000 -10000000000000000 0\n10000000000000000\n", + ); + ucmd() + .arg("{ print $1 * 1 }") + .pipe_in("5e20\n") + .succeeds() + .stdout_only("500000000000000000000\n"); +}