Source file src/strconv/number.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 (
     8  	"errors"
     9  	"internal/strconv"
    10  	"internal/stringslite"
    11  )
    12  
    13  // IntSize is the size in bits of an int or uint value.
    14  const IntSize = strconv.IntSize
    15  
    16  // ParseBool returns the boolean value represented by the string.
    17  // It accepts 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False.
    18  // Any other value returns an error.
    19  func ParseBool(str string) (bool, error) {
    20  	x, err := strconv.ParseBool(str)
    21  	if err != nil {
    22  		return x, toError("ParseBool", str, 0, 0, err)
    23  	}
    24  	return x, nil
    25  }
    26  
    27  // FormatBool returns "true" or "false" according to the value of b.
    28  func FormatBool(b bool) string {
    29  	return strconv.FormatBool(b)
    30  }
    31  
    32  // AppendBool appends "true" or "false", according to the value of b,
    33  // to dst and returns the extended buffer.
    34  func AppendBool(dst []byte, b bool) []byte {
    35  	return strconv.AppendBool(dst, b)
    36  }
    37  
    38  // ParseComplex converts the string s to a complex number
    39  // with the precision specified by bitSize: 64 for complex64, or 128 for complex128.
    40  // When bitSize=64, the result still has type complex128, but it will be
    41  // convertible to complex64 without changing its value.
    42  //
    43  // The number represented by s must be of the form N, Ni, or N±Ni, where N stands
    44  // for a floating-point number as recognized by [ParseFloat], and i is the imaginary
    45  // component. If the second N is unsigned, a + sign is required between the two components
    46  // as indicated by the ±. If the second N is NaN, only a + sign is accepted.
    47  // The form may be parenthesized and cannot contain any spaces.
    48  // The resulting complex number consists of the two components converted by ParseFloat.
    49  //
    50  // The errors that ParseComplex returns have concrete type [*NumError]
    51  // and include err.Num = s.
    52  //
    53  // If s is not syntactically well-formed, ParseComplex returns err.Err = ErrSyntax.
    54  //
    55  // If s is syntactically well-formed but either component is more than 1/2 ULP
    56  // away from the largest floating point number of the given component's size,
    57  // ParseComplex returns err.Err = ErrRange and c = ±Inf for the respective component.
    58  func ParseComplex(s string, bitSize int) (complex128, error) {
    59  	x, err := strconv.ParseComplex(s, bitSize)
    60  	if err != nil {
    61  		return x, toError("ParseComplex", s, 0, bitSize, err)
    62  	}
    63  	return x, nil
    64  }
    65  
    66  // ParseFloat converts the string s to a floating-point number
    67  // with the precision specified by bitSize: 32 for float32, or 64 for float64.
    68  // When bitSize=32, the result still has type float64, but it will be
    69  // convertible to float32 without changing its value.
    70  //
    71  // ParseFloat accepts decimal and hexadecimal floating-point numbers
    72  // as defined by the Go syntax for [floating-point literals].
    73  // If s is well-formed and near a valid floating-point number,
    74  // ParseFloat returns the nearest floating-point number rounded
    75  // using IEEE754 unbiased rounding.
    76  // (Parsing a hexadecimal floating-point value only rounds when
    77  // there are more bits in the hexadecimal representation than
    78  // will fit in the mantissa.)
    79  //
    80  // The errors that ParseFloat returns have concrete type *NumError
    81  // and include err.Num = s.
    82  //
    83  // If s is not syntactically well-formed, ParseFloat returns err.Err = ErrSyntax.
    84  //
    85  // If s is syntactically well-formed but is more than 1/2 ULP
    86  // away from the largest floating point number of the given size,
    87  // ParseFloat returns f = ±Inf, err.Err = ErrRange.
    88  //
    89  // ParseFloat recognizes the string "NaN", and the (possibly signed) strings "Inf" and "Infinity"
    90  // as their respective special floating point values. It ignores case when matching.
    91  //
    92  // [floating-point literals]: https://go.dev/ref/spec#Floating-point_literals
    93  func ParseFloat(s string, bitSize int) (float64, error) {
    94  	x, err := strconv.ParseFloat(s, bitSize)
    95  	if err != nil {
    96  		return x, toError("ParseFloat", s, 0, bitSize, err)
    97  	}
    98  	return x, nil
    99  }
   100  
   101  // ParseUint is like [ParseInt] but for unsigned numbers.
   102  //
   103  // A sign prefix is not permitted.
   104  func ParseUint(s string, base int, bitSize int) (uint64, error) {
   105  	x, err := strconv.ParseUint(s, base, bitSize)
   106  	if err != nil {
   107  		return x, toError("ParseUint", s, base, bitSize, err)
   108  	}
   109  	return x, nil
   110  }
   111  
   112  // ParseInt interprets a string s in the given base (0, 2 to 36) and
   113  // bit size (0 to 64) and returns the corresponding value i.
   114  //
   115  // The string may begin with a leading sign: "+" or "-".
   116  //
   117  // If the base argument is 0, the true base is implied by the string's
   118  // prefix following the sign (if present): 2 for "0b", 8 for "0" or "0o",
   119  // 16 for "0x", and 10 otherwise. Also, for argument base 0 only,
   120  // underscore characters are permitted as defined by the Go syntax for
   121  // [integer literals].
   122  //
   123  // The bitSize argument specifies the integer type
   124  // that the result must fit into. Bit sizes 0, 8, 16, 32, and 64
   125  // correspond to int, int8, int16, int32, and int64.
   126  // If bitSize is below 0 or above 64, an error is returned.
   127  //
   128  // The errors that ParseInt returns have concrete type [*NumError]
   129  // and include err.Num = s. If s is empty or contains invalid
   130  // digits, err.Err = [ErrSyntax] and the returned value is 0;
   131  // if the value corresponding to s cannot be represented by a
   132  // signed integer of the given size, err.Err = [ErrRange] and the
   133  // returned value is the maximum magnitude integer of the
   134  // appropriate bitSize and sign.
   135  //
   136  // [integer literals]: https://go.dev/ref/spec#Integer_literals
   137  func ParseInt(s string, base int, bitSize int) (i int64, err error) {
   138  	x, err := strconv.ParseInt(s, base, bitSize)
   139  	if err != nil {
   140  		return x, toError("ParseInt", s, base, bitSize, err)
   141  	}
   142  	return x, nil
   143  }
   144  
   145  // Atoi is equivalent to ParseInt(s, 10, 0), converted to type int.
   146  func Atoi(s string) (int, error) {
   147  	x, err := strconv.Atoi(s)
   148  	if err != nil {
   149  		return x, toError("Atoi", s, 0, 0, err)
   150  	}
   151  	return strconv.Atoi(s)
   152  }
   153  
   154  // FormatComplex converts the complex number c to a string of the
   155  // form (a+bi) where a and b are the real and imaginary parts,
   156  // formatted according to the format fmt and precision prec.
   157  //
   158  // The format fmt and precision prec have the same meaning as in [FormatFloat].
   159  // It rounds the result assuming that the original was obtained from a complex
   160  // value of bitSize bits, which must be 64 for complex64 and 128 for complex128.
   161  func FormatComplex(c complex128, fmt byte, prec, bitSize int) string {
   162  	return strconv.FormatComplex(c, fmt, prec, bitSize)
   163  }
   164  
   165  // FormatFloat converts the floating-point number f to a string,
   166  // according to the format fmt and precision prec. It rounds the
   167  // result assuming that the original was obtained from a floating-point
   168  // value of bitSize bits (32 for float32, 64 for float64).
   169  //
   170  // The format fmt is one of
   171  //   - 'b' (-ddddp±ddd, a binary exponent),
   172  //   - 'e' (-d.dddde±dd, a decimal exponent),
   173  //   - 'E' (-d.ddddE±dd, a decimal exponent),
   174  //   - 'f' (-ddd.dddd, no exponent),
   175  //   - 'g' ('e' for large exponents, 'f' otherwise),
   176  //   - 'G' ('E' for large exponents, 'f' otherwise),
   177  //   - 'x' (-0xd.ddddp±ddd, a hexadecimal fraction and binary exponent), or
   178  //   - 'X' (-0Xd.ddddP±ddd, a hexadecimal fraction and binary exponent).
   179  //
   180  // The precision prec controls the number of digits (excluding the exponent)
   181  // printed by the 'e', 'E', 'f', 'g', 'G', 'x', and 'X' formats.
   182  // For 'e', 'E', 'f', 'x', and 'X', it is the number of digits after the decimal point.
   183  // For 'g' and 'G' it is the maximum number of significant digits (trailing
   184  // zeros are removed).
   185  // The special precision -1 uses the smallest number of digits
   186  // necessary such that ParseFloat will return f exactly.
   187  // The exponent is written as a decimal integer;
   188  // for all formats other than 'b', it will be at least two digits.
   189  func FormatFloat(f float64, fmt byte, prec, bitSize int) string {
   190  	return strconv.FormatFloat(f, fmt, prec, bitSize)
   191  }
   192  
   193  // AppendFloat appends the string form of the floating-point number f,
   194  // as generated by [FormatFloat], to dst and returns the extended buffer.
   195  func AppendFloat(dst []byte, f float64, fmt byte, prec, bitSize int) []byte {
   196  	return strconv.AppendFloat(dst, f, fmt, prec, bitSize)
   197  }
   198  
   199  // FormatUint returns the string representation of i in the given base,
   200  // for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z'
   201  // for digit values >= 10.
   202  func FormatUint(i uint64, base int) string {
   203  	return strconv.FormatUint(i, base)
   204  }
   205  
   206  // FormatInt returns the string representation of i in the given base,
   207  // for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z'
   208  // for digit values >= 10.
   209  func FormatInt(i int64, base int) string {
   210  	return strconv.FormatInt(i, base)
   211  }
   212  
   213  // Itoa is equivalent to [FormatInt](int64(i), 10).
   214  func Itoa(i int) string {
   215  	return strconv.Itoa(i)
   216  }
   217  
   218  // AppendInt appends the string form of the integer i,
   219  // as generated by [FormatInt], to dst and returns the extended buffer.
   220  func AppendInt(dst []byte, i int64, base int) []byte {
   221  	return strconv.AppendInt(dst, i, base)
   222  }
   223  
   224  // AppendUint appends the string form of the unsigned integer i,
   225  // as generated by [FormatUint], to dst and returns the extended buffer.
   226  func AppendUint(dst []byte, i uint64, base int) []byte {
   227  	return strconv.AppendUint(dst, i, base)
   228  }
   229  
   230  // toError converts from internal/strconv.Error to the error guaranteed by this package's APIs.
   231  func toError(fn, s string, base, bitSize int, err error) error {
   232  	switch err {
   233  	case strconv.ErrSyntax:
   234  		return syntaxError(fn, s)
   235  	case strconv.ErrRange:
   236  		return rangeError(fn, s)
   237  	case strconv.ErrBase:
   238  		return baseError(fn, s, base)
   239  	case strconv.ErrBitSize:
   240  		return bitSizeError(fn, s, bitSize)
   241  	}
   242  	return err
   243  }
   244  
   245  // ErrRange indicates that a value is out of range for the target type.
   246  var ErrRange = errors.New("value out of range")
   247  
   248  // ErrSyntax indicates that a value does not have the right syntax for the target type.
   249  var ErrSyntax = errors.New("invalid syntax")
   250  
   251  // A NumError records a failed conversion.
   252  type NumError struct {
   253  	Func string // the failing function (ParseBool, ParseInt, ParseUint, ParseFloat, ParseComplex)
   254  	Num  string // the input
   255  	Err  error  // the reason the conversion failed (e.g. ErrRange, ErrSyntax, etc.)
   256  }
   257  
   258  func (e *NumError) Error() string {
   259  	return "strconv." + e.Func + ": " + "parsing " + Quote(e.Num) + ": " + e.Err.Error()
   260  }
   261  
   262  func (e *NumError) Unwrap() error { return e.Err }
   263  
   264  // All ParseXXX functions allow the input string to escape to the error value.
   265  // This hurts strconv.ParseXXX(string(b)) calls where b is []byte since
   266  // the conversion from []byte must allocate a string on the heap.
   267  // If we assume errors are infrequent, then we can avoid escaping the input
   268  // back to the output by copying it first. This allows the compiler to call
   269  // strconv.ParseXXX without a heap allocation for most []byte to string
   270  // conversions, since it can now prove that the string cannot escape Parse.
   271  
   272  func syntaxError(fn, str string) *NumError {
   273  	return &NumError{fn, stringslite.Clone(str), ErrSyntax}
   274  }
   275  
   276  func rangeError(fn, str string) *NumError {
   277  	return &NumError{fn, stringslite.Clone(str), ErrRange}
   278  }
   279  
   280  func baseError(fn, str string, base int) *NumError {
   281  	return &NumError{fn, stringslite.Clone(str), errors.New("invalid base " + Itoa(base))}
   282  }
   283  
   284  func bitSizeError(fn, str string, bitSize int) *NumError {
   285  	return &NumError{fn, stringslite.Clone(str), errors.New("invalid bit size " + Itoa(bitSize))}
   286  }
   287  

View as plain text