-
Notifications
You must be signed in to change notification settings - Fork 43
/
Copy pathFloats.v3
93 lines (90 loc) · 3.03 KB
/
Floats.v3
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
// Copyright 2021 Ben L. Titzer. All rights reserved.
// See LICENSE for details of Apache 2.0 license.
component Floats {
def d_minus0 = 0x80000000_00000000uL;
def d_nan = 0x7ff80000_00000000uL;
def d_1p1 = 0x40000000_00000000uL; // 2^1 as double
def d_1p31 = 0x41e00000_00000000uL; // 2^31 as double
def d_1p32 = 0x41f00000_00000000uL;
def d_1p33 = 0x42000000_00000000uL;
def d_1p63 = 0x43e00000_00000000uL;
def d_1p64 = 0x43f00000_00000000uL;
def d_minus1p31 = 0xc1e00000_00000000uL; // -2^31 as double
def d_minus1p32 = 0xc1f00000_00000000uL;
def d_minus1p33 = 0xc2000000_00000000uL;
def d_minus1p63 = 0xc3e00000_00000000uL;
def d_minus1p64 = 0xc3f00000_00000000uL;
def d_minus1 = 0xbff00000_00000000uL;
def d_infinity = 0x7ff0000000000000uL;
def d_minus_infinity = 0xfff0000000000000uL;
def f_minus0 = 0x8000_0000u;
def f_nan = 0x7fc0_0000u;
def f_1p1 = 0x4000_0000u;
def f_1p31 = 0x4f00_0000u;
def f_1p32 = 0x4f80_0000u;
def f_1p33 = 0x5000_0000u;
def f_1p63 = 0x5f00_0000u;
def f_1p64 = 0x5f80_0000u;
def f_minus1p31 = 0xcf00_0000u;
def f_minus1p32 = 0xcf80_0000u;
def f_minus1p33 = 0xd000_0000u;
def f_minus1p63 = 0xdf00_0000u;
def f_minus1p64 = 0xdf80_0000u;
def f_minus1 = 0xbf80_0000u;
def f_infinity = 0x7f800000u;
def f_minus_infinity = 0xff800000u;
def isNan32(bits: u32) -> bool {
if ((bits & 0x7F80_0000) != 0x7F80_0000) return false;
if ((bits << 9) == 0) return false;
return true;
}
def isNan64(bits: u64) -> bool {
if ((bits & 0x7FF00000_00000000) != 0x7FF00000_00000000) return false;
if ((bits << 12) == 0) return false;
return true;
}
def f32_bits(sign: int, exp: int, mantissa: u32) -> u32 {
var bits = if(sign != 0, 0x80000000u);
if (exp < -149) return bits;
if (exp <= -127) {
// subnormal; make implicit 1 explicit and shift right
mantissa = 0x80000000u | mantissa >> 1;
mantissa = mantissa >> u5.view(-127 - exp);
exp = -127;
} else if (exp >= 128) {
// saturate large exponents to infinity
return if (sign != 0, f_minus_infinity, f_infinity);
}
bits |= (u32.view(u8.view(exp + 127)) << 23);
bits |= u32.view(mantissa >> 9);
return bits;
}
def f64_bits(sign: int, exp: int, mantissa: u64) -> u64 {
var bits = if(sign != 0, 0x8000000000000000ul);
if (exp < -1076) return bits;
if (exp <= -1023) {
// subnormal; make implicit 1 explicit and shift right
mantissa = 0x8000000000000000ul | mantissa >> 1;
mantissa = mantissa >> u6.view(-1023 - exp);
exp = -1023;
} else if (exp >= 1024) {
// saturate large exponents to infinity
return if (sign != 0, d_minus_infinity, d_infinity);
}
bits |= (u64.view(u11.view(exp + 1023)) << 52);
bits |= mantissa >> 12;
return bits;
}
def f32_nan_bits(sign: int, mantissa: u32) -> u32 {
var bits = if(sign != 0, 0x80000000u);
bits |= (u32.view(u8.view(255)) << 23);
bits |= u32.view(mantissa >> 9);
return bits;
}
def f64_nan_bits(sign: int, mantissa: u64) -> u64 {
var bits = if(sign != 0, 0x8000000000000000ul);
bits |= (u64.view(u11.view(2047)) << 52);
bits |= mantissa >> 12;
return bits;
}
}