...

Source file src/math/floor.go

Documentation: math

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

View as plain text