package ftoaimport ()const ( digits = "0123456789abcdefghijklmnopqrstuvwxyz")func ( float64, int) string {varboolif < 0 { = - = true } := math.Floor() := int64()varstringif == float64() {if { = - } = strconv.FormatInt(, ) } else { := math.Float64bits() := int(>>exp_shiftL) & exp_mask_shiftedvarint64if == 0 { = int64(( & frac_maskL) << 1) } else { = int64(( & frac_maskL) | exp_msk1L) }if { = - } -= 1075 := big.NewInt()if > 0 { .Lsh(, uint()) } elseif < 0 { .Rsh(, uint(-)) } = .Text() }if == {// No fraction partreturn } else {/* We have a fraction. */varstrings.Builder .WriteString() .WriteByte('.') := - := math.Float64bits() := uint32( >> 32) := uint32() := make([]byte, 0, 8) , , := d2b(, )// JS_ASSERT(e < 0); /* At this point df = b * 2^e. e must be less than zero because 0 < df < 1. */ := -int(( >> exp_shift1) & (exp_mask >> exp_shift1))if == 0 { = -1 } += bias + p/* 1/2^s2 = (nextDouble(d) - d)/2 */ // JS_ASSERT(-s2 < e);if - >= {panic(fmt.Errorf("-s2 >= e: %d, %d", -, )) } := big.NewInt(1) := if ( == 0) && (( & bndry_mask) == 0) && (( & (exp_mask & (exp_mask << 1))) != 0) {/* The special case. Here we want to be within a quarter of the last input significant digit instead of one half of it when the output string's value is less than d. */ += log2P = big.NewInt(1 << log2P) } := new(big.Int).SetBytes() .Lsh(, uint(+)) := big.NewInt(1) .Lsh(, uint())/* At this point we have the following: * s = 2^s2; * 1 > df = b/2^s2 > 0; * (d - prevDouble(d))/2 = mlo/2^s2; * (nextDouble(d) - d)/2 = mhi/2^s2. */ := big.NewInt(int64()) := false := &big.Int{} := &big.Int{}for ! { .Mul(, ) .DivMod(, , ) := byte(.Int64()) , = , .Mul(, )if != { .Mul(, ) }/* Do we yet have the shortest string that will round to d? */ := .Cmp()/* j is b/2^s2 compared with mlo/2^s2. */ .Sub(, )varintif .Sign() <= 0 { = 1 } else { = .Cmp() }/* j1 is b/2^s2 compared with 1 - mhi/2^s2. */if == 0 && (&1) == 0 {if > 0 { ++ } = true } elseif < 0 || ( == 0 && (( & 1) == 0)) {if > 0 {/* Either dig or dig+1 would work here as the least significant digit. Use whichever would produce an output value closer to d. */ .Lsh(, 1) = .Cmp()if > 0 { /* The even test (|| (j1 == 0 && (digit & 1))) is not here because it messes up odd base output such as 3.5 in base 3. */ ++ } } = true } elseif > 0 { ++ = true }// JS_ASSERT(digit < (uint32)base); .WriteByte(digits[]) }return .String() }}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.