shithub: mc

ref: e08060746f8d0f1f42f8eeefb4fa6a699a6d331e
dir: /lib/math/test/pown-impl.myr/

View raw version
use std
use math
use testr

const main = {
	math.fptrap(false)
	testr.run([
		[.name="pown-01", .fn = pown01],
		[.name="pown-02", .fn = pown02],
		[.name="pown-03", .fn = pown03],
	][:])
}

const int32fromuint32 = {b; -> (&b : int32#)#}
const int64fromuint64 = {b; -> (&b : int64#)#}

/* Mostly obtained from fpmath-consensus */
const pown01 = {c
	var inputs : (uint32, uint32, uint32)[:] = [
		(0x000000f6, 0x00000000, 0x3f800000),
		(0x00000000, 0x3d800000, 0x00000000),
		(0x946fc13b, 0x3b21efc7, 0x80000000),
		(0xb76e98b6, 0xdbeb6637, 0xff800000),
		(0xc04825b7, 0x53cdd772, 0x7f800000),
		(0x3f7ff8c0, 0x000a53ba, 0x097c15ec),
		(0xbefb4dd0, 0xffffffc6, 0x5d3b4cbc),
		(0xbf77a88b, 0x0000038f, 0xa9b0342c),
		(0xbd5cdf23, 0xffffffeb, 0xebb17f33),
		(0x3fb66246, 0x000000e0, 0x78ac13ae),
		(0x3bfec3ab, 0x00000005, 0x2df9e189),
		(0x3f7762db, 0x000002b8, 0x2e466343),
		(0x3e245431, 0xfffffff7, 0x4b582b71),
		(0xbf73903f, 0x00000328, 0x2276ffa9),
		(0x3f6a088a, 0xfffffe4d, 0x5b9dcb2e),
		(0xc06650d6, 0x00000019, 0xd691b004),
		(0x3f751050, 0x00000731, 0x0583b3e2),
		(0x3f8124aa, 0x00001e6d, 0x7171d834),
		(0xbf6c06b0, 0x000001b2, 0x260cb0e7),
		(0x38307acf, 0x00000003, 0x29a7bd3a),
		(0x3f7fafa1, 0x00005c97, 0x2a835867),
		(0xbf80fb78, 0xfffffdcb, 0xbc5a0a5b),
		(0xbff532bd, 0xffffffe7, 0xb3bc09eb),
		(0xbf804fe0, 0x00002cbb, 0xd39529b4),
		(0xbf7eaac3, 0x000026c1, 0x9a1b5779),
		(0xb6ecbef2, 0xfffffff9, 0xfb5d43d7),
		(0x40c1d332, 0xffffffef, 0x29628a12),
	][:]

	for (x, y, z) : inputs
		var xf : flt32 = std.flt32frombits(x)
		var yi : int32 = int32fromuint32(y)
		var zf : flt32 = std.flt32frombits(z)
		var rf = math.pown(xf, yi)
		testr.check(c, rf == zf,
			"pown(0x{b=16,w=8,p=0}, {}) should be 0x{b=16,w=8,p=0}, was 0x{b=16,w=8,p=0}",
			x, yi, z, std.flt32bits(rf))
	;;
}

/* Mostly obtained from fpmath-consensus */
const pown02 = {c
	var inputs : (uint64, uint64, uint64)[:] = [
		(0x212c65442137286a, 0x000000007f47df7c, 0x0000000000000000),
		(0x9add65abd325b6eb, 0xfc2b1173d2f9d7c5, 0xfff0000000000000),
		(0xc00616fb023b43b5, 0x57ce36258314fd54, 0x7ff0000000000000),
		(0xc12300696c144c98, 0x0000000000000032, 0x7c152603516d90a8),
		(0xbfd3dfdfc81e60e0, 0xfffffffffffffe8a, 0x675fe457fecdc77b),
		(0xbff03687f3c6d148, 0xffffffffffffa5ce, 0x2465ab45a663c6e7),
		(0x3feae36a83f91b30, 0xfffffffffffff2a9, 0x75864016b705ed6e),
		(0x3feb9a4d0abc8192, 0xffffffffffffff7f, 0x41a6cb5da02a95f7),
		(0xbfbf733faaeccb42, 0xffffffffffffffc8, 0x4a851d5e1c674b7c),
		(0xbff0a5cfa8cc163b, 0xfffffffffffffc2c, 0x3c6dbc034c342e8e),
		(0xbfee9beac6a3caf0, 0xffffffffffffef92, 0x50c94fc31f862949),
		(0x4cba94fc5ab93856, 0xfffffffffffffffe, 0x26572fe2438caeb6),
		(0x3feccc63016da0b8, 0x00000000000010a3, 0x17735a1a2b8d1115),
		(0x3ff06cc390fe6413, 0x0000000000006183, 0x7aec68e2525e0756),
		(0xbfef7da61a3fc45e, 0x0000000000003c20, 0x29ac311e57d77bb2),
		(0xbd17d3142424b4ce, 0x000000000000000d, 0x9b061d29ecc312d7),
		(0xbd9b46e7dcf5ddd7, 0xffffffffffffffee, 0x69d1b75168c2d601),
		(0x3fb885ed105fdf42, 0x000000000000004b, 0x301272ca384d27ab),
		(0xbfedd75714c016db, 0x00000000000004a5, 0xb8723796de107a57),
		(0x3ff25198b971bb27, 0x00000000000012f3, 0x7b21bc435390825e),
		(0x3fef791958603e0e, 0xffffffffffff85b6, 0x6ecebfe2dc493669),
		(0xc017043172d0152b, 0x00000000000000e9, 0xe4b2c1666379afdc),
		(0xc0325800cfeffb8e, 0x00000000000000d8, 0x78983c24a5e29e19),
		(0xbfee2ae3cd3208ec, 0x00000000000006b7, 0xb6cb06585f39893d),
	][:]

	for (x, y, z) : inputs
		var xf : flt64 = std.flt64frombits(x)
		var yi : int64 = int64fromuint64(y)
		var zf : flt64 = std.flt64frombits(z)
		var rf = math.pown(xf, yi)
		testr.check(c, rf == zf,
			"pown(0x{b=16,w=16,p=0}, {}) should be 0x{b=16,w=16,p=0}, was 0x{b=16,w=16,p=0}",
			x, yi, z, std.flt64bits(rf))
	;;
}

/* Here we quarantine off some known-bad results */
const pown03 = {c
	var inputs : (uint32, uint32, uint32, uint32)[:] = [
		(0x3f80040a, 0xfff6d0a0, 0x09f93f64, 0x09f93f63),
		(0x409d7f5a, 0xffffffd5, 0x0e0c8fa0, 0x0e0c8f9f),
		(0xbfb588b4, 0x0000008c, 0x62be78b9, 0x62be78ba), 
		(0xb5e0d8c0, 0x00000002, 0x2c457c08, 0x2c457c07),
	][:]

	for (x, y, z_perfect, z_accepted) : inputs
		var xf : flt32 = std.flt32frombits(x)
		var yi : int32 = int32fromuint32(y)
		var zf_perfect : flt32 = std.flt32frombits(z_perfect)
		var zf_accepted : flt32 = std.flt32frombits(z_accepted)
		var rf = math.pown(xf, yi)
		testr.check(c, rf == zf_perfect || rf == zf_accepted,
			"pown(0x{b=16,w=8,p=0}, {}) should be 0x{b=16,w=8,p=0}, will also accept 0x{b=16,w=8,p=0}, was 0x{b=16,w=8,p=0}",
			x, yi, z_perfect, z_accepted, std.flt32bits(rf))
	;;
}