code wiki / _hdl_build / nx_f64_log2.nx
nx_f64_log2.nx source
↩ module page · 62 lines · 3147 B
1// AUTHORED BY THE NISHI BUILDER (pattern: MATH_KERNEL / LOG2_REDUCE).
2// Base-2 log, binary64 bits-up. Structure from LOG_REDUCE; constants from the
3// sovereign _pm_log_spec (oracle-generated). log2(x)=k+ln(m)/ln2.
4import "nx_syscalls.nx"
5import "nx_tier.nx"
6import "nx_f64.nx"
7import "nx_f64_div.nx"
8import "nx_f64_cvt.nx"
9const K_MAGIC_6369051672525773: i64 = 6369051672525773
10const K_MAGIC_4607182418800017408: i64 = 4607182418800017408
11const K_MAGIC_4590930298405593444: i64 = 4590930298405593444
12const K_MAGIC_4591527048666777112: i64 = 4591527048666777112
13const K_MAGIC_4592249430561894184: i64 = 4592249430561894184
14const K_MAGIC_4593141784667627038: i64 = 4593141784667627038
15const K_MAGIC_4593971859893063953: i64 = 4593971859893063953
16const K_MAGIC_4594710912139606804: i64 = 4594710912139606804
17const K_MAGIC_4595718710657619782: i64 = 4595718710657619782
18const K_MAGIC_4597174419628082972: i64 = 4597174419628082972
19const K_MAGIC_4598818590920615058: i64 = 4598818590920615058
20const K_MAGIC_4600877379321698714: i64 = 4600877379321698714
21const K_MAGIC_4604180019048437077: i64 = 4604180019048437077
22const K_MAGIC_4604418534062161920: i64 = 4604418534062161920
23const K_MAGIC_4494016781675590265: i64 = 4494016781675590265
24func nx_f64_log2(x: i64) -> i64 {
25 let cls: nx_int = nx_f64_classify(x)
26 if cls == NX_F64_CLS_NAN { return NX_F64_NAN_RAW }
27 if cls == NX_F64_CLS_ZERO { return 0xFFF0000000000000 }
28 if nx_f64_sign(x) == 1 { return NX_F64_NAN_RAW }
29 if cls == NX_F64_CLS_INF { return x }
30 var sig: i64 = nx_f64_mant_field(x)
31 var ef: i64 = nx_f64_exp_field(x)
32 if ef == 0 {
33 ef = 1
34 while sig < NX_F64_IMPLICIT_1 { sig = sig << 1; ef = ef - 1 }
35 } else {
36 sig = sig | NX_F64_IMPLICIT_1
37 }
38 var k: i64 = ef - 1023
39 var mexp: i64 = 1023
40 if sig >= K_MAGIC_6369051672525773 { k = k + 1; mexp = 1022 }
41 let mfv: i64 = (mexp << 52) | (sig & NX_F64_MANT_MASK)
42 let f: i64 = nx_f64_sub(mfv, K_MAGIC_4607182418800017408)
43 let two: i64 = nx_f64_add(K_MAGIC_4607182418800017408, K_MAGIC_4607182418800017408)
44 let s: i64 = nx_f64_div(f, nx_f64_add(two, f))
45 let z: i64 = nx_f64_mul(s, s)
46 var p: i64 = K_MAGIC_4590930298405593444
47 p = nx_f64_add(nx_f64_mul(p, z), K_MAGIC_4591527048666777112)
48 p = nx_f64_add(nx_f64_mul(p, z), K_MAGIC_4592249430561894184)
49 p = nx_f64_add(nx_f64_mul(p, z), K_MAGIC_4593141784667627038)
50 p = nx_f64_add(nx_f64_mul(p, z), K_MAGIC_4593971859893063953)
51 p = nx_f64_add(nx_f64_mul(p, z), K_MAGIC_4594710912139606804)
52 p = nx_f64_add(nx_f64_mul(p, z), K_MAGIC_4595718710657619782)
53 p = nx_f64_add(nx_f64_mul(p, z), K_MAGIC_4597174419628082972)
54 p = nx_f64_add(nx_f64_mul(p, z), K_MAGIC_4598818590920615058)
55 p = nx_f64_add(nx_f64_mul(p, z), K_MAGIC_4600877379321698714)
56 p = nx_f64_add(nx_f64_mul(p, z), K_MAGIC_4604180019048437077)
57 let r: i64 = nx_f64_mul(z, p)
58 let lnm: i64 = nx_f64_sub(f, nx_f64_mul(s, nx_f64_sub(f, r)))
59 let kf: i64 = nx_i64_to_f64(k)
60 let ln2: i64 = nx_f64_add(K_MAGIC_4604418534062161920, K_MAGIC_4494016781675590265)
61 return nx_f64_add(kf, nx_f64_div(lnm, ln2))
62}