From af5cc55cf070db544cc110e0a126c1c8b6bf2e8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20A=C4=9Facan?= Date: Fri, 12 Dec 2025 11:29:40 +0000 Subject: [PATCH 1/3] Fix Int64.toRadixStringUnsigned extra leading digits Currently this adds an extra '0' when the result is single digit, e.g. '02' instead of '2'. To be able to use the standard library `toRadixString`, we split the number into two halves, then calculate the lowest digit and the rest of the digits separately. With the lowest digit removed, the rest of the digits can be passed as a positive integer to `toRadixString`. The resulting strings are then concatenated to get the final result. The problem occurs when the number can be printed as a single digit. In this case the rest of the number can be printed as '0', giving us e.g. '02' instead of '2'. To fix, we return early by calling the standard library `toRadixString` when the high 32 bits are zero. This works because - The problem is only when printing single digits (as the lowest digit and the rest are printed separately, and the problem is when the "rest" part is 0) - Single-digit numbers need to have high 32-bits as zero (otherwise they'll be negative and printed as many digits, or positive but larger than single digit). - When the high 32-bits are all zero, the number is positive, and can be converted to string with the standard library signed `toRadixString`. --- pkgs/fixnum/lib/src/int64_native.dart | 6 +++--- pkgs/fixnum/test/int64_test.dart | 19 ++++++++++++++++++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/pkgs/fixnum/lib/src/int64_native.dart b/pkgs/fixnum/lib/src/int64_native.dart index b15bc99b..58d1cd98 100644 --- a/pkgs/fixnum/lib/src/int64_native.dart +++ b/pkgs/fixnum/lib/src/int64_native.dart @@ -362,11 +362,11 @@ class Int64 implements IntX { throw ArgumentError('toStringRadixUnsigned radix must be >= 2 and <= 36' ' (found $radix)'); } - if (value == 0) { - return '0'; - } // Split value into two 32-bit unsigned digits (v1, v0). final v1 = value >>> 32; + if (v1 == 0) { + return value.toRadixString(radix); + } var v0 = value.toUnsigned(32); // Long division by a single digit: (q1, q0) = (v1, v0) ~/ radix, remainder r0. final q1 = v1 ~/ radix; diff --git a/pkgs/fixnum/test/int64_test.dart b/pkgs/fixnum/test/int64_test.dart index e4bdd440..c711f19e 100644 --- a/pkgs/fixnum/test/int64_test.dart +++ b/pkgs/fixnum/test/int64_test.dart @@ -1140,7 +1140,24 @@ void main() { }); test('toStringUnsigned', () { - List values = []; + expect(Int64.MAX_VALUE.toStringUnsigned(), '9223372036854775807'); + expect(Int32.MAX_VALUE.toInt64().toStringUnsigned(), '2147483647'); + expect(Int64(2).toStringUnsigned(), '2'); + expect(Int64(1).toStringUnsigned(), '1'); + expect(Int64(0).toStringUnsigned(), '0'); + expect(Int64(-1).toStringUnsigned(), '18446744073709551615'); + expect(Int64(-2).toStringUnsigned(), '18446744073709551614'); + expect( + Int32.MIN_VALUE.toInt64().toStringUnsigned(), '18446744071562067968'); + expect(Int64.MIN_VALUE.toStringUnsigned(), '9223372036854775808'); + + List values = [ + Int64.MAX_VALUE, + Int64(1), + Int64(0), + Int64(-1), + Int64.MIN_VALUE, + ]; for (int high = 0; high < 16; high++) { for (int low = -2; low <= 2; low++) { values.add((Int64(high) << (64 - 4)) + Int64(low)); From a9ae12aab1ca4ff5d3f70dc148b14367514bf80c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20A=C4=9Facan?= Date: Fri, 12 Dec 2025 11:50:05 +0000 Subject: [PATCH 2/3] Fix formatting --- pkgs/fixnum/lib/src/int64_native.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/fixnum/lib/src/int64_native.dart b/pkgs/fixnum/lib/src/int64_native.dart index 58d1cd98..e0e8a5a7 100644 --- a/pkgs/fixnum/lib/src/int64_native.dart +++ b/pkgs/fixnum/lib/src/int64_native.dart @@ -364,7 +364,7 @@ class Int64 implements IntX { } // Split value into two 32-bit unsigned digits (v1, v0). final v1 = value >>> 32; - if (v1 == 0) { + if (v1 == 0) { return value.toRadixString(radix); } var v0 = value.toUnsigned(32); From 6510786cd08fa196ce3d976480c56eebba92cd2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20A=C4=9Facan?= Date: Fri, 12 Dec 2025 12:58:06 +0000 Subject: [PATCH 3/3] Simplify --- pkgs/fixnum/lib/src/int64_native.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/fixnum/lib/src/int64_native.dart b/pkgs/fixnum/lib/src/int64_native.dart index e0e8a5a7..69bd4484 100644 --- a/pkgs/fixnum/lib/src/int64_native.dart +++ b/pkgs/fixnum/lib/src/int64_native.dart @@ -362,11 +362,11 @@ class Int64 implements IntX { throw ArgumentError('toStringRadixUnsigned radix must be >= 2 and <= 36' ' (found $radix)'); } - // Split value into two 32-bit unsigned digits (v1, v0). - final v1 = value >>> 32; - if (v1 == 0) { + if (value >= 0) { return value.toRadixString(radix); } + // Split value into two 32-bit unsigned digits (v1, v0). + final v1 = value >>> 32; var v0 = value.toUnsigned(32); // Long division by a single digit: (q1, q0) = (v1, v0) ~/ radix, remainder r0. final q1 = v1 ~/ radix;