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"); +}