| // Copyright 2017 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| 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. |
| func isNaN(f float64) (is bool) { |
| // IEEE 754 says that only NaNs satisfy f != f. |
| return f != f |
| } |
| |
| // isFinite reports whether f is neither NaN nor an infinity. |
| func isFinite(f float64) bool { |
| return !isNaN(f - f) |
| } |
| |
| // isInf reports whether f is an infinity. |
| func isInf(f float64) bool { |
| return !isNaN(f) && !isFinite(f) |
| } |
| |
| // abs returns the absolute value of x. |
| // |
| // Special cases are: |
| // |
| // abs(±Inf) = +Inf |
| // abs(NaN) = NaN |
| func abs(x float64) float64 { |
| const sign = 1 << 63 |
| return float64frombits(float64bits(x) &^ sign) |
| } |
| |
| // copysign returns a value with the magnitude |
| // of x and the sign of y. |
| func copysign(x, y float64) float64 { |
| const sign = 1 << 63 |
| return float64frombits(float64bits(x)&^sign | float64bits(y)&sign) |
| } |
| |
| // float64bits returns the IEEE 754 binary representation of f. |
| func float64bits(f float64) uint64 { |
| return *(*uint64)(unsafe.Pointer(&f)) |
| } |
| |
| // float64frombits returns the floating point number corresponding |
| // the IEEE 754 binary representation b. |
| 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 |
| } |