gitee.com/quant1x/num@v0.3.2/math32/sqrt.go (about)

     1  package math32
     2  
     3  func Sqrt(x float32) float32
     4  
     5  // TODO: add assembly for !build noasm
     6  func sqrt(x float32) float32 {
     7  	// special cases
     8  	switch {
     9  	case x == 0 || IsNaN(x) || IsInf(x, 1):
    10  		return x
    11  	case x < 0:
    12  		return NaN()
    13  	}
    14  	ix := Float32bits(x)
    15  
    16  	// normalize x
    17  	exp := int((ix >> shift) & mask)
    18  	if exp == 0 { // subnormal x
    19  		for ix&(1<<shift) == 0 {
    20  			ix <<= 1
    21  			exp--
    22  		}
    23  		exp++
    24  	}
    25  	exp -= bias // unbias exponent
    26  	ix &^= mask << shift
    27  	ix |= 1 << shift
    28  	if exp&1 == 1 { // odd exp, double x to make it even
    29  		ix <<= 1
    30  	}
    31  	exp >>= 1 // exp = exp/2, exponent of square root
    32  	// generate sqrt(x) bit by bit
    33  	ix <<= 1
    34  	var q, s uint32               // q = sqrt(x)
    35  	r := uint32(1 << (shift + 1)) // r = moving bit from MSB to LSB
    36  	for r != 0 {
    37  		t := s + r
    38  		if t <= ix {
    39  			s = t + r
    40  			ix -= t
    41  			q += r
    42  		}
    43  		ix <<= 1
    44  		r >>= 1
    45  	}
    46  	// final rounding
    47  	if ix != 0 { // remainder, result not exact
    48  		q += q & 1 // round according to extra bit
    49  	}
    50  	ix = q>>1 + uint32(exp-1+bias)<<shift // significand + biased exponent
    51  	return Float32frombits(ix)
    52  
    53  }