Skip to content

Commit 0ff5326

Browse files
committed
Don't calculate multiplier upfront
1 parent 6b42516 commit 0ff5326

File tree

2 files changed

+15
-3
lines changed

2 files changed

+15
-3
lines changed

spec/std/int_spec.cr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,5 +1191,9 @@ describe "Int" do
11911191
Int32.from_digits([1, 2, -1])
11921192
end
11931193
end
1194+
1195+
it "works properly for values close to the upper limit" do
1196+
UInt8.from_digits([5, 5, 2]).should eq(255)
1197+
end
11941198
end
11951199
end

src/int.cr

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2800,9 +2800,10 @@ end
28002800
end
28012801

28022802
num : {{type.id}} = 0
2803-
multiplier = 1
2803+
multiplier : {{type.id}} = 1
2804+
first_element = true
28042805

2805-
digits.each do |digit|
2806+
digits.each_with_index do |digit, i|
28062807
if digit < 0
28072808
raise ArgumentError.new("Invalid digit #{digit}")
28082809
end
@@ -2811,8 +2812,15 @@ end
28112812
raise ArgumentError.new("Invalid digit #{digit} for base #{base}")
28122813
end
28132814

2815+
# don't calculate multiplier upfront for the next digit
2816+
# to avoid overflow at the last iteration
2817+
if first_element
2818+
first_element = false
2819+
else
2820+
multiplier *= base
2821+
end
2822+
28142823
num += digit * multiplier
2815-
multiplier *= base
28162824
end
28172825

28182826
num

0 commit comments

Comments
 (0)