performance - Avoiding integer overflow in Nim -


i started learning nim yesterday , decided code little test make performance comparison rust. code easy write , works values 10^9. however, need test @ least 10^12, gives incorrect values because of overflow, while using uint.

i've been trying different conversions variables can't seem avoid overflow. of course, suggestions make code easier read more welcome!

import math import sequtils import unsigned  proc sum_min_pfactor(n : uint) : uint =     proc f(n : uint) : uint =         return n*(n+1) div 2 - 1     var         v = int(math.sqrt(float(n)))         used = newseqwith(v+1,false)         s_sum,s_cnt,l_cnt,l_sum = newseq[uint](v+1)         ret = 0.uint     in -1..v-1:         s_cnt[i+1] = i.uint     in 0..v:         s_sum[i] = f(i.uint)     in 1..v:         l_cnt[i] = n div i.uint - 1         l_sum[i] = f(n div i.uint)     p in 2..v:         if s_cnt[p] == s_cnt[p-1]:             continue         var p_cnt = s_cnt[p - 1]         var p_sum = s_sum[p - 1]         var q = p * p         ret += p.uint * (l_cnt[p] - p_cnt)         l_cnt[1] -= l_cnt[p] - p_cnt         l_sum[1] -= (l_sum[p] - p_sum) * p.uint         var interval = (p , 1) + 1         var finish = min(v,n.int div q)         in countup(p+interval,finish,interval):             if used[i]:                 continue             var d = * p             if d <= v:                 l_cnt[i] -= l_cnt[d] - p_cnt                 l_sum[i] -= (l_sum[d] - p_sum) * p.uint             else:                 var t = n.int div d                 l_cnt[i] -= s_cnt[t] - p_cnt                 l_sum[i] -= (s_sum[t] - p_sum) * p.uint         if q <= v:             in countup(q,finish-1,p*interval):                 used[i] = true         in countdown(v,q-1):             var t = div p             s_cnt[i] -= s_cnt[t] - p_cnt             s_sum[i] -= (s_sum[t] - p_sum) * p.uint     return l_sum[1] + ret  echo(sum_min_pfactor(uint(math.pow(10,2)))) 

how solve in rust? rust's ints should 64bit @ most. in f function gets bit difficult when n 10000000000. have few choices:

some stylistic changes:

import math  proc sum_min_pfactor(n: int): int =   proc f(n: int): int =     n*(n+1) div 2 - 1    var     v = math.sqrt(n.float).int     s_cnt, s_sum, l_cnt, l_sum = newseq[int](v+1)     used = newseq[bool](v+1)    in 0..v: s_cnt[i] = i-1   in 1..v: s_sum[i] = f(i)   in 1..v: l_cnt[i] = n div - 1   in 1..v: l_sum[i] = f(n div i)    p in 2..v:     if s_cnt[p] == s_cnt[p-1]:       continue      let       p_cnt = s_cnt[p - 1]       p_sum = s_sum[p - 1]       q = p * p      result += p * (l_cnt[p] - p_cnt)     l_cnt[1] -= l_cnt[p] - p_cnt     l_sum[1] -= (l_sum[p] - p_sum) *  p      let interval = (p , 1) + 1     let finish = min(v,n div q)      in countup(p+interval,finish,interval):       if used[i]:         continue       let d = * p       if d <= v:         l_cnt[i] -= l_cnt[d] - p_cnt         l_sum[i] -= (l_sum[d] - p_sum) * p       else:         let t = n div d         l_cnt[i] -= s_cnt[t] - p_cnt         l_sum[i] -= (s_sum[t] - p_sum) * p      if q <= v:       in countup(q,finish-1,p*interval):         used[i] = true      in countdown(v,q-1):       let t = div p       s_cnt[i] -= s_cnt[t] - p_cnt       s_sum[i] -= (s_sum[t] - p_sum) * p    result += l_sum[1]  in 2..12:   echo sum_min_pfactor(int(math.pow(10,i.float))) 

Comments