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