Skip to content

Commit cbb4854

Browse files
authored
Fix Int64.toRadixStringUnsigned extra leading digits (#926)
Currently `Int64.toRadixStringUnsigned` 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 is printed as '0', giving us e.g. '02' instead of '2'. To fix, we return early by calling the standard library `toRadixString` when the number is positive. 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 directly with the standard library signed `toRadixString`.
1 parent 41a9e01 commit cbb4854

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

pkgs/fixnum/lib/src/int64_native.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,8 @@ class Int64 implements IntX {
364364
throw ArgumentError('toStringRadixUnsigned radix must be >= 2 and <= 36'
365365
' (found $radix)');
366366
}
367-
if (value == 0) {
368-
return '0';
367+
if (value >= 0) {
368+
return value.toRadixString(radix);
369369
}
370370
// Split value into two 32-bit unsigned digits (v1, v0).
371371
final v1 = value >>> 32;

pkgs/fixnum/test/int64_test.dart

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1140,7 +1140,24 @@ void main() {
11401140
});
11411141

11421142
test('toStringUnsigned', () {
1143-
List<Int64> values = [];
1143+
expect(Int64.MAX_VALUE.toStringUnsigned(), '9223372036854775807');
1144+
expect(Int32.MAX_VALUE.toInt64().toStringUnsigned(), '2147483647');
1145+
expect(Int64(2).toStringUnsigned(), '2');
1146+
expect(Int64(1).toStringUnsigned(), '1');
1147+
expect(Int64(0).toStringUnsigned(), '0');
1148+
expect(Int64(-1).toStringUnsigned(), '18446744073709551615');
1149+
expect(Int64(-2).toStringUnsigned(), '18446744073709551614');
1150+
expect(
1151+
Int32.MIN_VALUE.toInt64().toStringUnsigned(), '18446744071562067968');
1152+
expect(Int64.MIN_VALUE.toStringUnsigned(), '9223372036854775808');
1153+
1154+
List<Int64> values = [
1155+
Int64.MAX_VALUE,
1156+
Int64(1),
1157+
Int64(0),
1158+
Int64(-1),
1159+
Int64.MIN_VALUE,
1160+
];
11441161
for (int high = 0; high < 16; high++) {
11451162
for (int low = -2; low <= 2; low++) {
11461163
values.add((Int64(high) << (64 - 4)) + Int64(low));

0 commit comments

Comments
 (0)