code wiki / (root) / nx_bigfloat120_div.nx

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}