Skip to content

Commit f6a7731

Browse files
committed
Added Floats and Rounding
1 parent 2b3bd16 commit f6a7731

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

LowLevel/Floats.scope

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import "LowLevel/BitManip";
2+
3+
/%
4+
Returns the exponent of @"d" as a raw int.
5+
%/
6+
func int exponentPart(dec d) {
7+
ret and(shr(rawCastIntToDec(d), 52), 2047);
8+
}
9+
10+
/%
11+
Returns the mantissa of @"d" as a raw int.
12+
%/
13+
func int mantissaPart(dec d) {
14+
ret and(rawCastIntToDec(d), 4503599627370495);
15+
}

Math/Rounding.scope

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import "LowLevel/Floats";
2+
3+
/%
4+
Rounds @"input" down to the nearest whole.
5+
6+
`5.9` -> `5.0`
7+
`-86.1` -> `-86.0`
8+
`1.0` -> `1.0`
9+
%/
10+
func dec floor(dec input) {
11+
// Floating point magic!
12+
int asInt = rawCastDecToInt(input);
13+
int exponent = exponentPart(input) - 1023;
14+
if (exponent < 52) {
15+
if (exponent < 0) {
16+
// Return 0 * sign(input) if |input| < 1
17+
if (asInt > -1) {
18+
asInt = 0;
19+
} else if (and(asInt, 9223372036854775807) != 0) {
20+
asInt = -4616189618054758400;
21+
}
22+
} else {
23+
int i = shr(4503599627370495, exponent);
24+
25+
if (and(asInt, i) == 0) {
26+
ret input;
27+
}
28+
29+
if (asInt < 0) {
30+
// input is integral
31+
asInt += shr(4503599627370496, exponent);
32+
}
33+
34+
asInt = and(asInt, not(i));
35+
}
36+
37+
input = rawCastIntToDec(asInt);
38+
} else {
39+
// inf or NaN
40+
ret input + input;
41+
}
42+
43+
ret input;
44+
}

0 commit comments

Comments
 (0)