- 注册时间
- 2020-11-9
- 最后登录
- 1970-1-1
- 威望
- 星
- 金币
- 枚
- 贡献
- 分
- 经验
- 点
- 鲜花
- 朵
- 魅力
- 点
- 上传
- 次
- 下载
- 次
- 积分
- 3828
- 在线时间
- 小时
|
楼主 |
发表于 2021-1-28 16:47:20
|
显示全部楼层
本帖最后由 uk702 于 2021-1-28 16:50 编辑
采用两个精度,先是 double 精度进行粗算,再对临界值进行精算,将用时降到 10s 左右。
find 21440 sols, use time = 10.601999998092651
- # set JULIA_NUM_THREADS=8
- using Base.Threads
- t1=time();
- n=10^8; seg = 10000; ns=Int64(n/seg); u = log(2021.); v = log(2022.); w = log(10.0); c1=log(sqrt(2.0*pi))
- mylock = ReentrantLock()
- result = Channel{Int64}(ns)
- sols = Int64[]
- function check(g)
- global sols, mylock
- g = g*seg
- for n=g+2:g+seg+1
- h = c1 + log(n)*(n+0.5) - n;
- a = (h - u)/w; t = floor(Int, a);
- eps = v + t*w - h
- if eps > 0
- if eps > 0.001
- lock(mylock)
- sols=append!(sols, n)
- unlock(mylock)
- else
- h = c1 + log(n)*(big(n)+0.5) - big(n); a = (h - log(big(2021.)))/log(big(10.0)); t = floor(Int, a);
- if h < v + t*log(big(10.0))
- lock(mylock)
- sols=append!(sols, n)
- unlock(mylock)
- end
- end
-
- l = length(sols)
- if l % 1000 == 0 println("find $l sols ...") end
- end
- end
- put!(result, g)
- end
- @threads for i=0:ns-1
- check(i)
- end
- ct = 0; t = ns;
- while t > 1
- take!(result)
- global t = t - 1
- end
- for x in sols
- println(x)
- global ct += 1
- end
- println("find $ct sols, use time = $(time() - t1)")
复制代码 |
|