summaryrefslogtreecommitdiff
path: root/lib/std/test/fltbits.myr
blob: 1354c708382daf0e97be1672adcf40a2d13439a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
use std

use testr

const main = {
	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),
		     ][:]
		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
	for f : [1.0, 0.00001, 123.45, 1111111111111111.2, -1.9, -0.0001, std.flt32nan()][:]
		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, 0, -127),
			(true, 0, -127),
			(false, 0x399, -127),
			(true, 0x23, -127),
			(false, (1 << 23) | 0x23, 45),
			(true, (1 << 23) | 0x3a2, -12),
			(true, (1 << 23) | 0x3a1, -126),
		][:]
		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, 0, -1023),
			(true, 0, -1023),
			(false, 0x399, -1023),
			(true, 0x23, -1023),
			(false, (1 << 52) | 0xa33bc, 45),
			(true, (1 << 52) | 0x3, -12),
			(true, (1 << 52) | 0x11aabbcc, -200),
			(true, (1 << 52) | 0x3a1, 543),
			(true, (1 << 52) | 0x99aa228, 1001),
		][:]
		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))
	;;
}