Hi there
is it possibile to automatic convert from Int to BigInt?
Example:

puts (2**30)
puts (2**40)

the first line is ok, the second is an overflow… how can i provide a way to get an automatic conversion in situations like this? for example in a loop…

If you really want to do this, you can use exceptions:

require "big"
n = 1i8
increasing_size_ints = [Int8, Int16, Int32, Int64, BigInt]
max = BigInt.new(Int128::MAX)
max * 2
while n < max
begin
n *= 2
rescue
new_type = increasing_size_ints[increasing_size_ints.index(n.class).not_nil! + 1]
n = new_type.new(n)
n *= 2
end
end
p! n # => 170141183460469231731687303715884105728

Following up on this, if you need growing integers you really ought to use BigInt. On my machine, it was 3 times faster for the code above.

Full Code

require "big"
require "time"
max = BigInt.new(Int128::MAX)
max * 2
increasing_size_ints = [Int8, Int16, Int32, Int64, BigInt]
n = 1i8
# growing ints
n_time = Time.measure do
while n < max
begin
n *= 2
rescue
new_type = increasing_size_ints[increasing_size_ints.index(n.class).not_nil! + 1]
n = new_type.new(n)
n *= 2
end
end
end
m = BigInt.new(1)
# big_int
m_time = Time.measure do
while m < max
m *= 2
end
end
p! n, n_time
p! m, m_time

Output

n # => 170141183460469231731687303715884105728
n_time # => 00:00:00.000033894
m # => 170141183460469231731687303715884105728
m_time # => 00:00:00.000010804

I guess if the issue is that you want to keep the data types small when the values are small, maybe the exception approach works, but honestly I’m not even sure that’s true for unions like that.