code wiki / (root) / nx_money_gate.nx

nx_money_gate.nx source

↩ module page · 69 lines · 3433 B

1// nx_money_gate.nx -- R1 GATE: proves nx_money is exact + no-float. Asserts add/sub/neg, rounding 2// (floor / half-up / banker's half-even on positive, negative, and .5 ties), scaled-rate interest, 3// APR->monthly, the percent constructor, and [-]D.CC formatting against hand-computed vectors. 4// Exits 0 iff ALL pass (RED otherwise). license_tier: ORIGINAL 5import "nx_syscalls.nx" 6import "nx_money.nx" 7 8func g_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 9func g_putn(v: i64) -> i64 { 10 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 } 11 var m: i64 = v 12 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 13 let d: *u8 = sys_mmap(24); var k: i64 = 0 14 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 15 var j: i64 = k - 1 16 while j >= 0 { sys_write(1, ((d as i64)+j) as *u8, 1); j = j - 1 } 17 return 0 18} 19func chk(name: *u8, got: i64, want: i64, st: *i64) -> i64 { 20 if got == want { st[0] = st[0] + 1; g_puts(" PASS "); g_puts(name); g_puts("\n") } 21 else { st[1] = st[1] + 1; g_puts(" FAIL "); g_puts(name); g_puts(" got="); g_putn(got); g_puts(" want="); g_putn(want); g_puts("\n") } 22 return 0 23} 24 25func main() -> i64 { 26 let st: *i64 = sys_mmap(16) as *i64 27 st[0] = 0; st[1] = 0 28 29 // exact add / sub / neg 30 chk("add 100.50+29.99=130.49" as *u8, mny_add(10050, 2999), 13049, st) 31 chk("sub 100.00-25.75=74.25" as *u8, mny_sub(10000, 2575), 7425, st) 32 chk("neg 5.00=-5.00" as *u8, mny_neg(500), 0 - 500, st) 33 34 // rounding: half-even ties -> even; half-up ties -> away from zero; floor -> -inf 35 chk("HE 5/2=2" as *u8, mny_div_round(5, 2, RND_HALF_EVEN), 2, st) 36 chk("HE 7/2=4" as *u8, mny_div_round(7, 2, RND_HALF_EVEN), 4, st) 37 chk("HU 5/2=3" as *u8, mny_div_round(5, 2, RND_HALF_UP), 3, st) 38 chk("HE -5/2=-2" as *u8, mny_div_round(0 - 5, 2, RND_HALF_EVEN), 0 - 2, st) 39 chk("HU -5/2=-3" as *u8, mny_div_round(0 - 5, 2, RND_HALF_UP), 0 - 3, st) 40 chk("FLOOR -7/2=-4" as *u8, mny_div_round(0 - 7, 2, RND_FLOOR), 0 - 4, st) 41 chk("HE 4/2=2" as *u8, mny_div_round(4, 2, RND_HALF_EVEN), 2, st) 42 43 // rate constructor + apply: 5% of $100.00 = $5.00 44 let r5: i64 = mny_rate_from_pct(5, 1) 45 chk("rate 5% scaled=5e7" as *u8, r5, 50000000, st) 46 chk("5% of 100.00=5.00" as *u8, mny_apply_rate(10000, r5, RND_HALF_EVEN), 500, st) 47 48 // 6.5% APR monthly interest on $10,000.00 = $54.17 49 let apr: i64 = mny_rate_from_pct(65, 10) 50 chk("apr 6.5% scaled=6.5e7" as *u8, apr, 65000000, st) 51 let mr: i64 = mny_rate_monthly(apr) 52 chk("monthly 6.5%/12=5416667" as *u8, mr, 5416667, st) 53 chk("interest 10000.00 @mo=54.17" as *u8, mny_apply_rate(1000000, mr, RND_HALF_EVEN), 5417, st) 54 55 // formatting 56 let buf: *u8 = sys_mmap(32) 57 chk("fmt 5.00 len=4" as *u8, mny_format(500, buf), 4, st) 58 chk("fmt 5.00[0]='5'" as *u8, buf[0] as i64, 0x35, st) 59 chk("fmt 0.07 len=4" as *u8, mny_format(7, buf), 4, st) 60 chk("fmt 0.07 tens='0'" as *u8, buf[2] as i64, 0x30, st) 61 chk("fmt 0.07 ones='7'" as *u8, buf[3] as i64, 0x37, st) 62 chk("fmt -123.45 len=7" as *u8, mny_format(0 - 12345, buf), 7, st) 63 chk("fmt -123.45[0]='-'" as *u8, buf[0] as i64, 0x2d, st) 64 65 g_puts("nx_money_gate: PASS="); g_putn(st[0]); g_puts(" FAIL="); g_putn(st[1]); g_puts("\n") 66 if st[1] == 0 { g_puts("R1 nx_money: GREEN\n"); return 0 } 67 g_puts("R1 nx_money: RED\n") 68 return 1 69}