167 lines · 5.8 KB · Text
RawDownload
use stduse testruse math const main = {	math.fptrap(false)	testr.run([		[.name = "isnan", .fn = isnan01],		[.name = "bits-roundtrip-32", .fn = bitsround32],		[.name = "bits-roundtrip-64", .fn = bitsround64],		[.name = "flt32bits", .fn = flt32bits],		[.name = "flt64bits", .fn = flt64bits],		[.name = "explode-roundtrip-32", .fn = exploderound32],		[.name = "explode-roundtrip-64", .fn = exploderound64],	][:])} const isnan01 = {c	testr.check(c, std.isnan(std.flt64nan()), "std.flt64nan() should give a NaN")	testr.check(c, std.isnan(std.flt32nan()), "std.flt32nan() should give a NaN") 	/*	   a NaN should be {any sign bit}, then {8 or 11 exponent	   bits, all 1}, then {any non-zero sequence of 23 or 52	   bits}	 */	testr.check(c, std.isnan(std.flt64frombits(0xfff0000500000000ul)), "0xfff0000500000000 should be a NaN")	testr.check(c, std.isnan(std.flt64frombits(0x7ff0000500000000ul)), "0x7ff0000500000000 should be a NaN")	testr.check(c, std.isnan(std.flt32frombits(0xff800090)), "0xff800090 should be a NaN")	testr.check(c, std.isnan(std.flt32frombits(0x7f800090)), "0x7f800090 should be a NaN") 	/* if the significand bits are all 0, it's an infinity instead */	testr.check(c, !std.isnan(std.flt64frombits(0x7ff0000000000000ul)), "Infinities[1] should not be NaNs")	testr.check(c, !std.isnan(std.flt64frombits(0xfff0000000000000ul)), "Infinities[2] should not be NaNs")	testr.check(c, !std.isnan(std.flt32frombits(0xff800000)), "Infinities[3] should not be NaNs")	testr.check(c, !std.isnan(std.flt32frombits(0x7f800000)), "Infinities[4] should not be NaNs")} const bitsround32 = {c	for f : [1.0, 0.00001, 123.45, 1111111111111111.2, -1.9, -0.0001][:]		var g = std.flt32frombits(std.flt32bits(f))		testr.check(c, f == g, "flt -> bits -> flt non-identity: {} != {}", f, g)	;; 	for u : [0x7af80000, 0x12ab9800, 0x00000000, 0x00000001, 0x80000000, 0xc8903aa5][:]		var v = std.flt32bits(std.flt32frombits(u))		testr.check(c, u == v, "bits -> flt -> bits non-identity: {} != {}", u, v)	;; 	var nan_f = std.flt32frombits(0xff800090)	var nan_g = std.flt32frombits(std.flt32bits(nan_f))	testr.check(c, nan_f == nan_g, "flt -> bits -> flt non-identity for nan") 	var inf_f = std.flt32frombits(0x7f800000)	var inf_g = std.flt32frombits(std.flt32bits(inf_f))	testr.check(c, inf_f == inf_g, "flt -> bits -> flt non-identity for inf")} const bitsround64 = {c	for f : [1.0, 0.00001, 123.45, 1111111111111111.2, -1.9, -0.0001][:]		var g = std.flt64frombits(std.flt64bits(f))		testr.check(c, f == g, "flt -> bits -> flt non-identity: {} != {}", f, g)	;; 	for u : [0x7ff3330a00120809, 0x0000000000000000, 0x0000000000000001, 0xffffff0000000001][:]		var v = std.flt64bits(std.flt64frombits(u))		testr.check(c, u == v, "bits -> flt -> bits non-identity: {} != {}", u, v)	;; 	var nan_f = std.flt64frombits(0x7ff000000000a000ul)	var nan_g = std.flt64frombits(std.flt64bits(nan_f))	testr.check(c, nan_f == nan_g, "flt -> bits -> flt non-identity for nan") 	var inf_f = std.flt64frombits(0xfff0000000000000ul)	var inf_g = std.flt64frombits(std.flt64bits(inf_f))	testr.check(c, inf_f == inf_g, "flt -> bits -> flt non-identity for inf")} const flt32bits = {c	for (f, u) : [			(2.0, 0x40000000),			(1.0, 0x3f800000),			(0.0000123, 0x374e5c19),			(-993.83, 0xc478751f),			(0.000000000000000000000000000000000000006054601, 0x0041edc4),		     ][:]		var uprime = std.flt32bits(f)		testr.check(c, u == uprime, "flt32bits wrong for {}:  0x{x} != 0x{x}", f, u, uprime)	;;} const flt64bits = {c	for (f, u) : [			(2.0, 0x4000000000000000ul),			(1.0, 0x3ff0000000000000ul),			(0.0000123, 0x3ee9cb8320b15070ul),			(-993.83, 0xc08f0ea3d70a3d71ul),		     ][:]		var uprime = std.flt64bits(f)		testr.check(c, u == uprime, "flt64bits wrong for {}:  0x{x} != 0x{x}", f, u, uprime)	;;} const exploderound32 = {c	var vals	vals = [1.0, 0.00001, 123.45, 1111111111111111.2, -1.9, -0.0001, 0.000000000000000000000000000000000000006054601, std.flt32nan()][:] 	for f : vals		var n, e, s		(n, e, s) = std.flt32explode(f)		var g = std.flt32assem(n, e, s)		testr.check(c, f == g, "assem o explode non-identity: {} != {}", f, g)	;; 	/*	   The exponents and significands need to be rather specific	   in order for flt32assem to work as expected	 */	for (n, e, s) : [			(false, -127, 0),			(true, -127, 0),			(false, -127, 0x399),			(true, -127, 0x23),			(false, 45, (1 << 23) | 0x23),			(true, -12, (1 << 23) | 0x3a2),			(true, -126, (1 << 23) | 0x3a1),			(false, -127, 4320708),		][:]		var m, f, t		(m, f, t) = std.flt32explode(std.flt32assem(n, e, s))		testr.check(c, n == m, "explode o assem non-identity: {} != {}", (n, e, s), (m, f, t))		testr.check(c, e == f, "explode o assem non-identity: {} != {}", (n, e, s), (m, f, t))		testr.check(c, s == t, "explode o assem non-identity: {} != {}", (n, e, s), (m, f, t))	;;} const exploderound64 = {c	for f : [1.0, 0.00001, 123.45, 1111111111111e+309, -1.9, -0.0001, std.flt64nan()][:]		var n, e, s		(n, e, s) = std.flt64explode(f)		var g = std.flt64assem(n, e, s)		testr.check(c, f == g, "assem o explode non-identity: {} != {}", f, g)	;; 	/*	   The exponents and significands need to be rather specific	   in order for flt32assem to work as expected	 */	for (n, e, s) : [			(false, -1023, 0),			(true, -1023, 0),			(false, -1023, 0x399),			(true, -1023, 0x23),			(false, 45, (1 << 52) | 0xa33bc),			(true, -12, (1 << 52) | 0x3),			(true, -200, (1 << 52) | 0x11aabbcc),			(true, 543, (1 << 52) | 0x3a1),			(true, 1001, (1 << 52) | 0x99aa228),		][:]		var m, f, t		(m, f, t) = std.flt64explode(std.flt64assem(n, e, s))		testr.check(c, n == m, "explode o assem non-identity: {} != {}", (n, e, s), (m, f, t))		testr.check(c, e == f, "explode o assem non-identity: {} != {}", (n, e, s), (m, f, t))		testr.check(c, s == t, "explode o assem non-identity: {} != {}", (n, e, s), (m, f, t))	;;}