Skip to content

Commit 6b42516

Browse files
committed
Define from_digits on concrete integer types
1 parent 7b75945 commit 6b42516

File tree

2 files changed

+50
-48
lines changed

2 files changed

+50
-48
lines changed

spec/std/int_spec.cr

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,40 +1155,40 @@ describe "Int" do
11551155

11561156
describe "from_digits" do
11571157
it "returns Int composed from given digits" do
1158-
Int.from_digits([9, 8, 7, 6, 5, 4, 3, 2, 1]).should eq(123456789)
1158+
Int32.from_digits([9, 8, 7, 6, 5, 4, 3, 2, 1]).should eq(123456789)
11591159
end
11601160

11611161
it "works with a base" do
1162-
Int.from_digits([11, 7], 16).should eq(123)
1163-
Int.from_digits([11, 7], base: 16).should eq(123)
1162+
Int32.from_digits([11, 7], 16).should eq(123)
1163+
Int32.from_digits([11, 7], base: 16).should eq(123)
11641164
end
11651165

11661166
it "accepts digits as Enumerable" do
11671167
enumerable = IntEnumerable.new([11, 7])
1168-
Int.from_digits(enumerable, 16).should eq(123)
1168+
Int32.from_digits(enumerable, 16).should eq(123)
11691169
end
11701170

11711171
it "raises for base less than 2" do
11721172
[-1, 0, 1].each do |base|
11731173
expect_raises(ArgumentError, "Invalid base #{base}") do
1174-
Int.from_digits([1, 2, 3], base)
1174+
Int32.from_digits([1, 2, 3], base)
11751175
end
11761176
end
11771177
end
11781178

11791179
it "raises for digits greater than base" do
11801180
expect_raises(ArgumentError, "Invalid digit 2 for base 2") do
1181-
Int.from_digits([1, 0, 2], 2)
1181+
Int32.from_digits([1, 0, 2], 2)
11821182
end
11831183

11841184
expect_raises(ArgumentError, "Invalid digit 10 for base 2") do
1185-
Int.from_digits([1, 0, 10], 2)
1185+
Int32.from_digits([1, 0, 10], 2)
11861186
end
11871187
end
11881188

11891189
it "raises for negative digits" do
11901190
expect_raises(ArgumentError, "Invalid digit -1") do
1191-
Int.from_digits([1, 2, -1])
1191+
Int32.from_digits([1, 2, -1])
11921192
end
11931193
end
11941194
end

src/int.cr

Lines changed: 42 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -670,46 +670,6 @@ struct Int
670670
ary
671671
end
672672

673-
# Returns a number for given digits and base.
674-
# The digits are expected as an Enumerable with the least significant digit as the first element.
675-
#
676-
# Base must not be less than 2.
677-
#
678-
# All digits must be within 0...base.
679-
#
680-
# ```
681-
# Int.from_digits([5, 4, 3, 2, 1]) # => 12345
682-
# Int.from_digits([4, 6, 6, 0, 5], base: 7) # => 12345
683-
# Int.from_digits([45, 23, 1], base: 100) # => 12345
684-
#
685-
# Int.from_digits([1], base: -2) # => ArgumentError
686-
# Int.from_digits([-1]) # => ArgumentError
687-
# Int.from_digits([3], base: 2) # => ArgumentError
688-
# ```
689-
def self.from_digits(digits : Enumerable(Int), base : Int = 10) : self
690-
if base < 2
691-
raise ArgumentError.new("Invalid base #{base}")
692-
end
693-
694-
num = 0
695-
multiplier = 1
696-
697-
digits.each do |digit|
698-
if digit < 0
699-
raise ArgumentError.new("Invalid digit #{digit}")
700-
end
701-
702-
if digit >= base
703-
raise ArgumentError.new("Invalid digit #{digit} for base #{base}")
704-
end
705-
706-
num += digit * multiplier
707-
multiplier *= base
708-
end
709-
710-
num
711-
end
712-
713673
private DIGITS_DOWNCASE = "0123456789abcdefghijklmnopqrstuvwxyz"
714674
private DIGITS_UPCASE = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
715675
private DIGITS_BASE62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -2816,3 +2776,45 @@ struct UInt128
28162776
self
28172777
end
28182778
end
2779+
2780+
# Returns a number for given digits and base.
2781+
# The digits are expected as an Enumerable with the least significant digit as the first element.
2782+
#
2783+
# Base must not be less than 2.
2784+
#
2785+
# All digits must be within 0...base.
2786+
#
2787+
# ```
2788+
# Int32.from_digits([5, 4, 3, 2, 1]) # => 12345
2789+
# Int32.from_digits([4, 6, 6, 0, 5], base: 7) # => 12345
2790+
# Int32.from_digits([45, 23, 1], base: 100) # => 12345
2791+
#
2792+
# Int32.from_digits([1], base: -2) # => ArgumentError
2793+
# Int32.from_digits([-1]) # => ArgumentError
2794+
# Int32.from_digits([3], base: 2) # => ArgumentError
2795+
# ```
2796+
{% for type in %w(Int8 Int16 Int32 Int64 Int128 UInt8 UInt16 UInt32 UInt64 UInt128) %}
2797+
def {{type.id}}.from_digits(digits : Enumerable(Int), base : Int = 10) : self
2798+
if base < 2
2799+
raise ArgumentError.new("Invalid base #{base}")
2800+
end
2801+
2802+
num : {{type.id}} = 0
2803+
multiplier = 1
2804+
2805+
digits.each do |digit|
2806+
if digit < 0
2807+
raise ArgumentError.new("Invalid digit #{digit}")
2808+
end
2809+
2810+
if digit >= base
2811+
raise ArgumentError.new("Invalid digit #{digit} for base #{base}")
2812+
end
2813+
2814+
num += digit * multiplier
2815+
multiplier *= base
2816+
end
2817+
2818+
num
2819+
end
2820+
{% end %}

0 commit comments

Comments
 (0)