Source file src/math/floor.go

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package math
     6  
     7  // Floor returns the greatest integer value less than or equal to x.
     8  //
     9  // Special cases are:
    10  //
    11  //	Floor(±0) = ±0
    12  //	Floor(±Inf) = ±Inf
    13  //	Floor(NaN) = NaN
    14  func Floor(x float64) float64 {
    15  	if haveArchFloor {
    16  		return archFloor(x)
    17  	}
    18  	return floor(x)
    19  }
    20  
    21  func floor(x float64) float64 {
    22  	if x == 0 || IsNaN(x) || IsInf(x, 0) {
    23  		return x
    24  	}
    25  	if x < 0 {
    26  		d, fract := Modf(-x)
    27  		if fract != 0.0 {
    28  			d = d + 1
    29  		}
    30  		return -d
    31  	}
    32  	d, _ := Modf(x)
    33  	return d
    34  }
    35  
    36  // Ceil returns the least integer value greater than or equal to x.
    37  //
    38  // Special cases are:
    39  //
    40  //	Ceil(±0) = ±0
    41  //	Ceil(±Inf) = ±Inf
    42  //	Ceil(NaN) = NaN
    43  func Ceil(x float64) float64 {
    44  	if haveArchCeil {
    45  		return archCeil(x)
    46  	}
    47  	return ceil(x)
    48  }
    49  
    50  func ceil(x float64) float64 {
    51  	return -Floor(-x)
    52  }
    53  
    54  // Trunc returns the integer value of x.
    55  //
    56  // Special cases are:
    57  //
    58  //	Trunc(±0) = ±0
    59  //	Trunc(±Inf) = ±Inf
    60  //	Trunc(NaN) = NaN
    61  func Trunc(x float64) float64 {
    62  	if haveArchTrunc {
    63  		return archTrunc(x)
    64  	}
    65  	return trunc(x)
    66  }
    67  
    68  func trunc(x float64) float64 {
    69  	if Abs(x) < 1 {
    70  		return Copysign(0, x)
    71  	}
    72  
    73  	b := Float64bits(x)
    74  	e := uint(b>>shift)&mask - bias
    75  
    76  	// Keep the top 12+e bits, the integer part; clear the rest.
    77  	if e < 64-12 {
    78  		b &^= 1<<(64-12-e) - 1
    79  	}
    80  	return Float64frombits(b)
    81  }
    82  
    83  // Round returns the nearest integer, rounding half away from zero.
    84  //
    85  // Special cases are:
    86  //
    87  //	Round(±0) = ±0
    88  //	Round(±Inf) = ±Inf
    89  //	Round(NaN) = NaN
    90  func Round(x float64) float64 {
    91  	// Round is a faster implementation of:
    92  	//
    93  	// func Round(x float64) float64 {
    94  	//   t := Trunc(x)
    95  	//   if Abs(x-t) >= 0.5 {
    96  	//     return t + Copysign(1, x)
    97  	//   }
    98  	//   return t
    99  	// }
   100  	bits := Float64bits(x)
   101  	e := uint(bits>>shift) & mask
   102  	if e < bias {
   103  		// Round abs(x) < 1 including denormals.
   104  		bits &= signMask // +-0
   105  		if e == bias-1 {
   106  			bits |= uvone // +-1
   107  		}
   108  	} else if e < bias+shift {
   109  		// Round any abs(x) >= 1 containing a fractional component [0,1).
   110  		//
   111  		// Numbers with larger exponents are returned unchanged since they
   112  		// must be either an integer, infinity, or NaN.
   113  		const half = 1 << (shift - 1)
   114  		e -= bias
   115  		bits += half >> e
   116  		bits &^= fracMask >> e
   117  	}
   118  	return Float64frombits(bits)
   119  }
   120  
   121  // RoundToEven returns the nearest integer, rounding ties to even.
   122  //
   123  // Special cases are:
   124  //
   125  //	RoundToEven(±0) = ±0
   126  //	RoundToEven(±Inf) = ±Inf
   127  //	RoundToEven(NaN) = NaN
   128  func RoundToEven(x float64) float64 {
   129  	// RoundToEven is a faster implementation of:
   130  	//
   131  	// func RoundToEven(x float64) float64 {
   132  	//   t := math.Trunc(x)
   133  	//   odd := math.Remainder(t, 2) != 0
   134  	//   if d := math.Abs(x - t); d > 0.5 || (d == 0.5 && odd) {
   135  	//     return t + math.Copysign(1, x)
   136  	//   }
   137  	//   return t
   138  	// }
   139  	bits := Float64bits(x)
   140  	e := uint(bits>>shift) & mask
   141  	if e >= bias {
   142  		// Round abs(x) >= 1.
   143  		// - Large numbers without fractional components, infinity, and NaN are unchanged.
   144  		// - Add 0.499.. or 0.5 before truncating depending on whether the truncated
   145  		//   number is even or odd (respectively).
   146  		const halfMinusULP = (1 << (shift - 1)) - 1
   147  		e -= bias
   148  		bits += (halfMinusULP + (bits>>(shift-e))&1) >> e
   149  		bits &^= fracMask >> e
   150  	} else if e == bias-1 && bits&fracMask != 0 {
   151  		// Round 0.5 < abs(x) < 1.
   152  		bits = bits&signMask | uvone // +-1
   153  	} else {
   154  		// Round abs(x) <= 0.5 including denormals.
   155  		bits &= signMask // +-0
   156  	}
   157  	return Float64frombits(bits)
   158  }
   159  

View as plain text