In the code below you see I explicitly set the shown values to be i64
64-bit values.
However, when it get close to the limit value, I notice some of them switching between i32
and i64
types. How can this happen? I set them to be (and always stay) i64
to explicitly to prevent overflow
.
start = Time.monotonic
print("The self-describing numbers are:")
i = 10i64 # self-describing number must end in 0
pw = 10i64 # power of 10
fd = 1i64 # first digit
sd = 1i64 # second digit
dg = 2i64 # number of digits
mx = 11i64 # maximum for current batch
lim = 9_100_000_001i64 # sum of digits can't be more than 10
while i < lim
if selfDesc(i)
secs = (Time.monotonic - start).total_seconds
print("\n#{i} in #{secs} secs")
end
i += 10
if i > mx
fd += 1
sd -= 1
if sd >= 0
i = fd * pw
else
pw *= 10
dg += 1
i = pw
fd = 1
sd = dg - 1
end
puts " i = #{i.class}, sd = #{sd.class}, pw = #{pw.class}, mx = #{mx.class}"
mx = i + sd * pw // 10
end
end
I inserted that puts
statement line before the line: mx = i + sd * pw // 10
because that’s where the error message said the over flow occurred.
Here’s the output just before it fails.
i = Int32, sd = Int64, pw = Int64, mx = Int32
i = Int32, sd = Int64, pw = Int64, mx = Int32
i = Int32, sd = Int64, pw = Int64, mx = Int32
i = Int32, sd = Int64, pw = Int64, mx = Int32
i = Int64, sd = Int64, pw = Int64, mx = Int32
i = Int32, sd = Int64, pw = Int64, mx = Int64
I finally figured out how to “fix” it by making all the constants in that inner loop i64
s.
But why should I have to do this? Why do the number types change to lower types?
if i > mx
fd += 1i64
sd -= 1i64
if sd >= 0
i = fd * pw
else
pw *= 10i64
dg += 1i64
i = pw
fd = 1i64
sd = dg - 1i64
end
#puts " i = #{i.class}, sd = #{sd.class}, pw = #{pw.class}, mx = #{mx.class}"
mx = i + sd * pw // 10