Source file src/internal/strconv/ftoafixed.go

     1  // Copyright 2025 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 strconv
     6  
     7  import "math/bits"
     8  
     9  var uint64pow10 = [...]uint64{
    10  	1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
    11  	1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
    12  }
    13  
    14  // fixedFtoa formats a number of decimal digits of mant*(2^exp) into d,
    15  // where mant > 0 and 1 ≤ digits ≤ 18.
    16  // If fmt == 'f', digits is a conservative overestimate, and the final
    17  // number of digits is prec past the decimal point.
    18  func fixedFtoa(d *decimalSlice, mant uint64, exp, digits, prec int, fmt byte) {
    19  	// The strategy here is to multiply (mant * 2^exp) by a power of 10
    20  	// to make the resulting integer be the number of digits we want.
    21  	//
    22  	// Adams proved in the Ryu paper that 128-bit precision in the
    23  	// power-of-10 constant is sufficient to produce correctly
    24  	// rounded output for all float64s, up to 18 digits.
    25  	// https://dl.acm.org/doi/10.1145/3192366.3192369
    26  	//
    27  	// TODO(rsc): The paper is not focused on, nor terribly clear about,
    28  	// this fact in this context, and the proof seems too complicated.
    29  	// Post a shorter, more direct proof and link to it here.
    30  
    31  	if digits > 18 {
    32  		panic("fixedFtoa called with digits > 18")
    33  	}
    34  
    35  	// Shift mantissa to have 64 bits,
    36  	// so that the 192-bit product below will
    37  	// have at least 63 bits in its top word.
    38  	b := 64 - bits.Len64(mant)
    39  	mant <<= b
    40  	exp -= b
    41  
    42  	// We have f = mant * 2^exp ≥ 2^(63+exp)
    43  	// and we want to multiply it by some 10^p
    44  	// to make it have the number of digits plus one rounding bit:
    45  	//
    46  	//	2 * 10^(digits-1) ≤ f * 10^p < ~2 * 10^digits
    47  	//
    48  	// The lower bound is required, but the upper bound is approximate:
    49  	// we must not have too few digits, but we can round away extra ones.
    50  	//
    51  	//	f * 10^p ≥ 2 * 10^(digits-1)
    52  	//	10^p ≥ 2 * 10^(digits-1) / f                         [dividing by f]
    53  	//	p ≥ (log₁₀ 2) + (digits-1) - log₁₀ f                 [taking log₁₀]
    54  	//	p ≥ (log₁₀ 2) + (digits-1) - log₁₀ (mant * 2^exp)    [expanding f]
    55  	//	p ≥ (log₁₀ 2) + (digits-1) - (log₁₀ 2) * (64 + exp)  [mant < 2⁶⁴]
    56  	//	p ≥ (digits - 1) - (log₁₀ 2) * (63 + exp)            [refactoring]
    57  	//
    58  	// Once we have p, we can compute the scaled value:
    59  	//
    60  	//	dm * 2^de = mant * 2^exp * 10^p
    61  	//	          = mant * 2^exp * pow/2^128 * 2^exp2.
    62  	//	          = (mant * pow/2^128) * 2^(exp+exp2).
    63  	p := (digits - 1) - mulLog10_2(63+exp)
    64  	pow, exp2, ok := pow10(p)
    65  	if !ok {
    66  		// This never happens due to the range of float32/float64 exponent
    67  		panic("fixedFtoa: pow10 out of range")
    68  	}
    69  	if -22 <= p && p < 0 {
    70  		// Special case: Let q=-p. q is in [1,22]. We are dividing by 10^q
    71  		// and the mantissa may be a multiple of 5^q (5^22 < 2^53),
    72  		// in which case the division must be computed exactly and
    73  		// recorded as exact for correct rounding. Our normal computation is:
    74  		//
    75  		//	dm = floor(mant * floor(10^p * 2^s))
    76  		//
    77  		// for some scaling shift s. To make this an exact division,
    78  		// it suffices to change the inner floor to a ceil:
    79  		//
    80  		//	dm = floor(mant * ceil(10^p * 2^s))
    81  		//
    82  		// In the range of values we are using, the floor and ceil
    83  		// cancel each other out and the high 64 bits of the product
    84  		// come out exactly right.
    85  		// (This is the same trick compilers use for division by constants.
    86  		// See Hacker's Delight, 2nd ed., Chapter 10.)
    87  		pow.Lo++
    88  	}
    89  	dm, lo1, lo0 := umul192(mant, pow)
    90  	de := exp + exp2
    91  
    92  	// Check whether any bits have been truncated from dm.
    93  	// If so, set dt != 0. If not, leave dt == 0 (meaning dm is exact).
    94  	var dt uint
    95  	switch {
    96  	default:
    97  		// Most powers of 10 use a truncated constant,
    98  		// meaning the result is also truncated.
    99  		dt = 1
   100  	case 0 <= p && p <= 55:
   101  		// Small positive powers of 10 (up to 10⁵⁵) can be represented
   102  		// precisely in a 128-bit mantissa (5⁵⁵ ≤ 2¹²⁸), so the only truncation
   103  		// comes from discarding the low bits of the 192-bit product.
   104  		//
   105  		// TODO(rsc): The new proof mentioned above should also
   106  		// prove that we can't have lo1 == 0 and lo0 != 0.
   107  		// After proving that, drop computation and use of lo0 here.
   108  		dt = bool2uint(lo1|lo0 != 0)
   109  	case -22 <= p && p < 0 && divisiblePow5(mant, -p):
   110  		// If the original mantissa was a multiple of 5^p,
   111  		// the result is exact. (See comment above for pow.Lo++.)
   112  		dt = 0
   113  	}
   114  
   115  	// The value we want to format is dm * 2^de, where de < 0.
   116  	// Multply by 2^de by shifting, but leave one extra bit for rounding.
   117  	// After the shift, the "integer part" of dm is dm>>1,
   118  	// the "rounding bit" (the first fractional bit) is dm&1,
   119  	// and the "truncated bit" (have any bits been discarded?) is dt.
   120  	shift := -de - 1
   121  	dt |= bool2uint(dm&(1<<shift-1) != 0)
   122  	dm >>= shift
   123  
   124  	// Set decimal point in eventual formatted digits,
   125  	// so we can update it as we adjust the digits.
   126  	d.dp = digits - p
   127  
   128  	// Trim excess digit if any, updating truncation and decimal point.
   129  	// The << 1 is leaving room for the rounding bit.
   130  	max := uint64pow10[digits] << 1
   131  	if dm >= max {
   132  		var r uint
   133  		dm, r = dm/10, uint(dm%10)
   134  		dt |= bool2uint(r != 0)
   135  		d.dp++
   136  	}
   137  
   138  	// If this is %.*f we may have overestimated the digits needed.
   139  	// Now that we know where the decimal point is,
   140  	// trim to the actual number of digits, which is d.dp+prec.
   141  	if fmt == 'f' && digits != d.dp+prec {
   142  		for digits > d.dp+prec {
   143  			var r uint
   144  			dm, r = dm/10, uint(dm%10)
   145  			dt |= bool2uint(r != 0)
   146  			digits--
   147  		}
   148  
   149  		// Dropping those digits can create a new leftmost
   150  		// non-zero digit, like if we are formatting %.1f and
   151  		// convert 0.09 -> 0.1. Detect and adjust for that.
   152  		if digits <= 0 {
   153  			digits = 1
   154  			d.dp++
   155  		}
   156  
   157  		max = uint64pow10[digits] << 1
   158  	}
   159  
   160  	// Round and shift away rounding bit.
   161  	// We want to round up when
   162  	// (a) the fractional part is > 0.5 (dm&1 != 0 and dt == 1)
   163  	// (b) or the fractional part is ≥ 0.5 and the integer part is odd
   164  	//     (dm&1 != 0 and dm&2 != 0).
   165  	// The bitwise expression encodes that logic.
   166  	dm += uint64(uint(dm) & (dt | uint(dm)>>1) & 1)
   167  	dm >>= 1
   168  	if dm == max>>1 {
   169  		// 999... rolled over to 1000...
   170  		dm = uint64pow10[digits-1]
   171  		d.dp++
   172  	}
   173  
   174  	// Format digits into d.
   175  	if dm != 0 {
   176  		if formatBase10(d.d[:digits], dm) != 0 {
   177  			panic("formatBase10")
   178  		}
   179  		d.nd = digits
   180  		for d.d[d.nd-1] == '0' {
   181  			d.nd--
   182  		}
   183  	}
   184  }
   185  

View as plain text