aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/float.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/float.go')
-rw-r--r--src/runtime/float.go79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/runtime/float.go b/src/runtime/float.go
index 9f281c4045..d8573c103b 100644
--- a/src/runtime/float.go
+++ b/src/runtime/float.go
@@ -6,6 +6,12 @@ package runtime
import "unsafe"
+const (
+ float64Mask = 0x7FF
+ float64Shift = 64 - 11 - 1
+ float64Bias = 1023
+)
+
var inf = float64frombits(0x7FF0000000000000)
// isNaN reports whether f is an IEEE 754 “not-a-number” value.
@@ -52,3 +58,76 @@ func float64bits(f float64) uint64 {
func float64frombits(b uint64) float64 {
return *(*float64)(unsafe.Pointer(&b))
}
+
+// floor returns the greatest integer value less than or equal to x.
+//
+// Special cases are:
+//
+// floor(±0) = ±0
+// floor(±Inf) = ±Inf
+// floor(NaN) = NaN
+//
+// N.B. Portable floor copied from math. math also has optimized arch-specific
+// implementations.
+func floor(x float64) float64 {
+ if x == 0 || isNaN(x) || isInf(x) {
+ return x
+ }
+ if x < 0 {
+ d, fract := modf(-x)
+ if fract != 0.0 {
+ d = d + 1
+ }
+ return -d
+ }
+ d, _ := modf(x)
+ return d
+}
+
+// ceil returns the least integer value greater than or equal to x.
+//
+// Special cases are:
+//
+// Ceil(±0) = ±0
+// Ceil(±Inf) = ±Inf
+// Ceil(NaN) = NaN
+//
+// N.B. Portable ceil copied from math. math also has optimized arch-specific
+// implementations.
+func ceil(x float64) float64 {
+ return -floor(-x)
+}
+
+// modf returns integer and fractional floating-point numbers
+// that sum to f. Both values have the same sign as f.
+//
+// Special cases are:
+//
+// Modf(±Inf) = ±Inf, NaN
+// Modf(NaN) = NaN, NaN
+//
+// N.B. Portable modf copied from math. math also has optimized arch-specific
+// implementations.
+func modf(f float64) (int float64, frac float64) {
+ if f < 1 {
+ switch {
+ case f < 0:
+ int, frac = modf(-f)
+ return -int, -frac
+ case f == 0:
+ return f, f // Return -0, -0 when f == -0
+ }
+ return 0, f
+ }
+
+ x := float64bits(f)
+ e := uint(x>>float64Shift)&float64Mask - float64Bias
+
+ // Keep the top 12+e bits, the integer part; clear the rest.
+ if e < 64-12 {
+ x &^= 1<<(64-12-e) - 1
+ }
+ int = float64frombits(x)
+ frac = f - int
+ return
+}