nx_bigfloat120_div.nx source
↩ module page · 56 lines · 1686 B
1// nx_bigfloat120_div.nx -- full 120-bit division (separate file: mul+div quirk law).
2//
3// Bit-serial restoring division on two-word significands: 121 quotient bits,
4// q = floor(asig * 2^120 / bsig) in (2^119, 2^121]; one conditional right shift
5// renormalizes. Remainder truncates (67 guard bits of margin -- core's contract).
6// license_tier: ORIGINAL
7
8import "nx_syscalls.nx"
9import "nx_tier.nx"
10import "nx_bigfloat120.nx"
11
12func bf_div(out: *i64, a: *i64, b: *i64) -> i64 {
13 if bf_is_zero(a) == 1 { return bf_copy(out, a) }
14 // caller never divides by zero (series denominators are constants)
15 var rh: i64 = a[1]
16 var rl: i64 = a[2]
17 let dh: i64 = b[1]
18 let dl: i64 = b[2]
19 var qh: i64 = 0
20 var ql: i64 = 0
21 var i: i64 = 0
22 while i <= 120 {
23 // q <<= 1
24 qh = ((qh << 1) | ((ql >> 59) & 1))
25 ql = (ql << 1) & BF_M60
26 // r >= d ?
27 var ge: i64 = 0
28 if rh > dh { ge = 1 }
29 if rh == dh { if rl >= dl { ge = 1 } }
30 if ge == 1 {
31 var nl: i64 = rl - dl
32 var bw: i64 = 0
33 if nl < 0 { nl = nl + BF_HI_TOP; bw = 1 }
34 rh = rh - dh - bw
35 rl = nl
36 ql = ql | 1
37 }
38 // r <<= 1
39 rh = (rh << 1) | ((rl >> 59) & 1)
40 rl = (rl << 1) & BF_M60
41 i = i + 1
42 }
43 // q has 121 or 120 bits; value = q * 2^(ea - eb - 120) ... normalize:
44 var e: i64 = a[0] - b[0]
45 if qh >= BF_HI_TOP {
46 ql = (ql >> 1) | ((qh & 1) << 59)
47 qh = qh >> 1
48 // e stays: 121-bit q means ratio in [1, 2)
49 } else {
50 e = e - 1
51 }
52 out[0] = e
53 out[1] = qh
54 out[2] = ql
55 return bf_norm(out)
56}