This question is about how the compiler deals with numerical constants at compile time.
The following code compiles without using the overflow operators &**
, etc. However at runtime, for large numbers inputs, it gives runtime overflow errors.
But most of these numbers are just representations of constants I thought would be precomputed at compile time, e.g. 46 &* 10 &**8
is the constant 4_600_000_000
.
Is my thinking wrong?
And in cases like this, is it better (for speed, mem, etc) to write out the values explicitly as constant numbers, or will the compiler do that anyway (but it seems it doesn’t)?
def select_pg(endnum, startnum)
start_num = end_num = typeof(endnum)
end_num = endnum; start_num = startnum
range = end_num - start_num
pg = 5
if start_num <= isqrt(end_num) #.to_u64 # for one array of primes upto N
pg = 7 if end_num > 50 * 10 &**4
pg = 11 if end_num > 305 * 10 &**5
else # for split array cases
pg = 7 if (10&**6 <= range < 10&**7 && start_num < 10 &**8) ||
(10&**7 <= range < 10&**8 && start_num < 46 &* 10 &**8) ||
(10&**8 <= range < 10&**9 && start_num < 16 &* 10 &**10) ||
(range >= 10&**9 && start_num < 26 &* 10 &**12)
pg = 11 if (10**8 <= range < 10&**9 && start_num < 55 &* 10 &**7) ||
(range >= 10&**9 && start_num < 45 &* 10 &**9)
end
primes = [2, 3, 5, 7, 11, 13].select { |p| p <= pg }
{primes, primes.product} # [excluded primes, modpg] for PG
end