github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/strconv/ftoa.go (about) 1 // Copyright 2009 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 // Binary to decimal floating point conversion. 6 // Algorithm: 7 // 1) store mantissa in multiprecision decimal 8 // 2) shift decimal by exponent 9 // 3) read digits out & format 10 11 package strconv 12 13 import "math" 14 15 // TODO: move elsewhere? 16 type floatInfo struct { 17 mantbits uint 18 expbits uint 19 bias int 20 } 21 22 var float32info = floatInfo{23, 8, -127} 23 var float64info = floatInfo{52, 11, -1023} 24 25 // FormatFloat converts the floating-point number f to a string, 26 // according to the format fmt and precision prec. It rounds the 27 // result assuming that the original was obtained from a floating-point 28 // value of bitSize bits (32 for float32, 64 for float64). 29 // 30 // The format fmt is one of 31 // 'b' (-ddddp±ddd, a binary exponent), 32 // 'e' (-d.dddde±dd, a decimal exponent), 33 // 'E' (-d.ddddE±dd, a decimal exponent), 34 // 'f' (-ddd.dddd, no exponent), 35 // 'g' ('e' for large exponents, 'f' otherwise), 36 // 'G' ('E' for large exponents, 'f' otherwise), 37 // 'x' (-0xd.ddddp±ddd, a hexadecimal fraction and binary exponent), or 38 // 'X' (-0Xd.ddddP±ddd, a hexadecimal fraction and binary exponent). 39 // 40 // The precision prec controls the number of digits (excluding the exponent) 41 // printed by the 'e', 'E', 'f', 'g', 'G', 'x', and 'X' formats. 42 // For 'e', 'E', 'f', 'x', and 'X', it is the number of digits after the decimal point. 43 // For 'g' and 'G' it is the maximum number of significant digits (trailing 44 // zeros are removed). 45 // The special precision -1 uses the smallest number of digits 46 // necessary such that ParseFloat will return f exactly. 47 func FormatFloat(f float64, fmt byte, prec, bitSize int) string { 48 return string(genericFtoa(make([]byte, 0, max(prec+4, 24)), f, fmt, prec, bitSize)) 49 } 50 51 // AppendFloat appends the string form of the floating-point number f, 52 // as generated by FormatFloat, to dst and returns the extended buffer. 53 func AppendFloat(dst []byte, f float64, fmt byte, prec, bitSize int) []byte { 54 return genericFtoa(dst, f, fmt, prec, bitSize) 55 } 56 57 func genericFtoa(dst []byte, val float64, fmt byte, prec, bitSize int) []byte { 58 var bits uint64 59 var flt *floatInfo 60 switch bitSize { 61 case 32: 62 bits = uint64(math.Float32bits(float32(val))) 63 flt = &float32info 64 case 64: 65 bits = math.Float64bits(val) 66 flt = &float64info 67 default: 68 panic("strconv: illegal AppendFloat/FormatFloat bitSize") 69 } 70 71 neg := bits>>(flt.expbits+flt.mantbits) != 0 72 exp := int(bits>>flt.mantbits) & (1<<flt.expbits - 1) 73 mant := bits & (uint64(1)<<flt.mantbits - 1) 74 75 switch exp { 76 case 1<<flt.expbits - 1: 77 // Inf, NaN 78 var s string 79 switch { 80 case mant != 0: 81 s = "NaN" 82 case neg: 83 s = "-Inf" 84 default: 85 s = "+Inf" 86 } 87 return append(dst, s...) 88 89 case 0: 90 // denormalized 91 exp++ 92 93 default: 94 // add implicit top bit 95 mant |= uint64(1) << flt.mantbits 96 } 97 exp += flt.bias 98 99 // Pick off easy binary, hex formats. 100 if fmt == 'b' { 101 return fmtB(dst, neg, mant, exp, flt) 102 } 103 if fmt == 'x' || fmt == 'X' { 104 return fmtX(dst, prec, fmt, neg, mant, exp, flt) 105 } 106 107 if !optimize { 108 return bigFtoa(dst, prec, fmt, neg, mant, exp, flt) 109 } 110 111 var digs decimalSlice 112 ok := false 113 // Negative precision means "only as much as needed to be exact." 114 shortest := prec < 0 115 if shortest { 116 // Use Ryu algorithm. 117 var buf [32]byte 118 digs.d = buf[:] 119 ryuFtoaShortest(&digs, mant, exp-int(flt.mantbits), flt) 120 ok = true 121 // Precision for shortest representation mode. 122 switch fmt { 123 case 'e', 'E': 124 prec = max(digs.nd-1, 0) 125 case 'f': 126 prec = max(digs.nd-digs.dp, 0) 127 case 'g', 'G': 128 prec = digs.nd 129 } 130 } else if fmt != 'f' { 131 // Fixed number of digits. 132 digits := prec 133 switch fmt { 134 case 'e', 'E': 135 digits++ 136 case 'g', 'G': 137 if prec == 0 { 138 prec = 1 139 } 140 digits = prec 141 default: 142 // Invalid mode. 143 digits = 1 144 } 145 var buf [24]byte 146 if bitSize == 32 && digits <= 9 { 147 digs.d = buf[:] 148 ryuFtoaFixed32(&digs, uint32(mant), exp-int(flt.mantbits), digits) 149 ok = true 150 } else if digits <= 18 { 151 digs.d = buf[:] 152 ryuFtoaFixed64(&digs, mant, exp-int(flt.mantbits), digits) 153 ok = true 154 } 155 } 156 if !ok { 157 return bigFtoa(dst, prec, fmt, neg, mant, exp, flt) 158 } 159 return formatDigits(dst, shortest, neg, digs, prec, fmt) 160 } 161 162 // bigFtoa uses multiprecision computations to format a float. 163 func bigFtoa(dst []byte, prec int, fmt byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte { 164 d := new(decimal) 165 d.Assign(mant) 166 d.Shift(exp - int(flt.mantbits)) 167 var digs decimalSlice 168 shortest := prec < 0 169 if shortest { 170 roundShortest(d, mant, exp, flt) 171 digs = decimalSlice{d: d.d[:], nd: d.nd, dp: d.dp} 172 // Precision for shortest representation mode. 173 switch fmt { 174 case 'e', 'E': 175 prec = digs.nd - 1 176 case 'f': 177 prec = max(digs.nd-digs.dp, 0) 178 case 'g', 'G': 179 prec = digs.nd 180 } 181 } else { 182 // Round appropriately. 183 switch fmt { 184 case 'e', 'E': 185 d.Round(prec + 1) 186 case 'f': 187 d.Round(d.dp + prec) 188 case 'g', 'G': 189 if prec == 0 { 190 prec = 1 191 } 192 d.Round(prec) 193 } 194 digs = decimalSlice{d: d.d[:], nd: d.nd, dp: d.dp} 195 } 196 return formatDigits(dst, shortest, neg, digs, prec, fmt) 197 } 198 199 func formatDigits(dst []byte, shortest bool, neg bool, digs decimalSlice, prec int, fmt byte) []byte { 200 switch fmt { 201 case 'e', 'E': 202 return fmtE(dst, neg, digs, prec, fmt) 203 case 'f': 204 return fmtF(dst, neg, digs, prec) 205 case 'g', 'G': 206 // trailing fractional zeros in 'e' form will be trimmed. 207 eprec := prec 208 if eprec > digs.nd && digs.nd >= digs.dp { 209 eprec = digs.nd 210 } 211 // %e is used if the exponent from the conversion 212 // is less than -4 or greater than or equal to the precision. 213 // if precision was the shortest possible, use precision 6 for this decision. 214 if shortest { 215 eprec = 6 216 } 217 exp := digs.dp - 1 218 if exp < -4 || exp >= eprec { 219 if prec > digs.nd { 220 prec = digs.nd 221 } 222 return fmtE(dst, neg, digs, prec-1, fmt+'e'-'g') 223 } 224 if prec > digs.dp { 225 prec = digs.nd 226 } 227 return fmtF(dst, neg, digs, max(prec-digs.dp, 0)) 228 } 229 230 // unknown format 231 return append(dst, '%', fmt) 232 } 233 234 // roundShortest rounds d (= mant * 2^exp) to the shortest number of digits 235 // that will let the original floating point value be precisely reconstructed. 236 func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) { 237 // If mantissa is zero, the number is zero; stop now. 238 if mant == 0 { 239 d.nd = 0 240 return 241 } 242 243 // Compute upper and lower such that any decimal number 244 // between upper and lower (possibly inclusive) 245 // will round to the original floating point number. 246 247 // We may see at once that the number is already shortest. 248 // 249 // Suppose d is not denormal, so that 2^exp <= d < 10^dp. 250 // The closest shorter number is at least 10^(dp-nd) away. 251 // The lower/upper bounds computed below are at distance 252 // at most 2^(exp-mantbits). 253 // 254 // So the number is already shortest if 10^(dp-nd) > 2^(exp-mantbits), 255 // or equivalently log2(10)*(dp-nd) > exp-mantbits. 256 // It is true if 332/100*(dp-nd) >= exp-mantbits (log2(10) > 3.32). 257 minexp := flt.bias + 1 // minimum possible exponent 258 if exp > minexp && 332*(d.dp-d.nd) >= 100*(exp-int(flt.mantbits)) { 259 // The number is already shortest. 260 return 261 } 262 263 // d = mant << (exp - mantbits) 264 // Next highest floating point number is mant+1 << exp-mantbits. 265 // Our upper bound is halfway between, mant*2+1 << exp-mantbits-1. 266 upper := new(decimal) 267 upper.Assign(mant*2 + 1) 268 upper.Shift(exp - int(flt.mantbits) - 1) 269 270 // d = mant << (exp - mantbits) 271 // Next lowest floating point number is mant-1 << exp-mantbits, 272 // unless mant-1 drops the significant bit and exp is not the minimum exp, 273 // in which case the next lowest is mant*2-1 << exp-mantbits-1. 274 // Either way, call it mantlo << explo-mantbits. 275 // Our lower bound is halfway between, mantlo*2+1 << explo-mantbits-1. 276 var mantlo uint64 277 var explo int 278 if mant > 1<<flt.mantbits || exp == minexp { 279 mantlo = mant - 1 280 explo = exp 281 } else { 282 mantlo = mant*2 - 1 283 explo = exp - 1 284 } 285 lower := new(decimal) 286 lower.Assign(mantlo*2 + 1) 287 lower.Shift(explo - int(flt.mantbits) - 1) 288 289 // The upper and lower bounds are possible outputs only if 290 // the original mantissa is even, so that IEEE round-to-even 291 // would round to the original mantissa and not the neighbors. 292 inclusive := mant%2 == 0 293 294 // As we walk the digits we want to know whether rounding up would fall 295 // within the upper bound. This is tracked by upperdelta: 296 // 297 // If upperdelta == 0, the digits of d and upper are the same so far. 298 // 299 // If upperdelta == 1, we saw a difference of 1 between d and upper on a 300 // previous digit and subsequently only 9s for d and 0s for upper. 301 // (Thus rounding up may fall outside the bound, if it is exclusive.) 302 // 303 // If upperdelta == 2, then the difference is greater than 1 304 // and we know that rounding up falls within the bound. 305 var upperdelta uint8 306 307 // Now we can figure out the minimum number of digits required. 308 // Walk along until d has distinguished itself from upper and lower. 309 for ui := 0; ; ui++ { 310 // lower, d, and upper may have the decimal points at different 311 // places. In this case upper is the longest, so we iterate from 312 // ui==0 and start li and mi at (possibly) -1. 313 mi := ui - upper.dp + d.dp 314 if mi >= d.nd { 315 break 316 } 317 li := ui - upper.dp + lower.dp 318 l := byte('0') // lower digit 319 if li >= 0 && li < lower.nd { 320 l = lower.d[li] 321 } 322 m := byte('0') // middle digit 323 if mi >= 0 { 324 m = d.d[mi] 325 } 326 u := byte('0') // upper digit 327 if ui < upper.nd { 328 u = upper.d[ui] 329 } 330 331 // Okay to round down (truncate) if lower has a different digit 332 // or if lower is inclusive and is exactly the result of rounding 333 // down (i.e., and we have reached the final digit of lower). 334 okdown := l != m || inclusive && li+1 == lower.nd 335 336 switch { 337 case upperdelta == 0 && m+1 < u: 338 // Example: 339 // m = 12345xxx 340 // u = 12347xxx 341 upperdelta = 2 342 case upperdelta == 0 && m != u: 343 // Example: 344 // m = 12345xxx 345 // u = 12346xxx 346 upperdelta = 1 347 case upperdelta == 1 && (m != '9' || u != '0'): 348 // Example: 349 // m = 1234598x 350 // u = 1234600x 351 upperdelta = 2 352 } 353 // Okay to round up if upper has a different digit and either upper 354 // is inclusive or upper is bigger than the result of rounding up. 355 okup := upperdelta > 0 && (inclusive || upperdelta > 1 || ui+1 < upper.nd) 356 357 // If it's okay to do either, then round to the nearest one. 358 // If it's okay to do only one, do it. 359 switch { 360 case okdown && okup: 361 d.Round(mi + 1) 362 return 363 case okdown: 364 d.RoundDown(mi + 1) 365 return 366 case okup: 367 d.RoundUp(mi + 1) 368 return 369 } 370 } 371 } 372 373 type decimalSlice struct { 374 d []byte 375 nd, dp int 376 } 377 378 // %e: -d.ddddde±dd 379 func fmtE(dst []byte, neg bool, d decimalSlice, prec int, fmt byte) []byte { 380 // sign 381 if neg { 382 dst = append(dst, '-') 383 } 384 385 // first digit 386 ch := byte('0') 387 if d.nd != 0 { 388 ch = d.d[0] 389 } 390 dst = append(dst, ch) 391 392 // .moredigits 393 if prec > 0 { 394 dst = append(dst, '.') 395 i := 1 396 m := min(d.nd, prec+1) 397 if i < m { 398 dst = append(dst, d.d[i:m]...) 399 i = m 400 } 401 for ; i <= prec; i++ { 402 dst = append(dst, '0') 403 } 404 } 405 406 // e± 407 dst = append(dst, fmt) 408 exp := d.dp - 1 409 if d.nd == 0 { // special case: 0 has exponent 0 410 exp = 0 411 } 412 if exp < 0 { 413 ch = '-' 414 exp = -exp 415 } else { 416 ch = '+' 417 } 418 dst = append(dst, ch) 419 420 // dd or ddd 421 switch { 422 case exp < 10: 423 dst = append(dst, '0', byte(exp)+'0') 424 case exp < 100: 425 dst = append(dst, byte(exp/10)+'0', byte(exp%10)+'0') 426 default: 427 dst = append(dst, byte(exp/100)+'0', byte(exp/10)%10+'0', byte(exp%10)+'0') 428 } 429 430 return dst 431 } 432 433 // %f: -ddddddd.ddddd 434 func fmtF(dst []byte, neg bool, d decimalSlice, prec int) []byte { 435 // sign 436 if neg { 437 dst = append(dst, '-') 438 } 439 440 // integer, padded with zeros as needed. 441 if d.dp > 0 { 442 m := min(d.nd, d.dp) 443 dst = append(dst, d.d[:m]...) 444 for ; m < d.dp; m++ { 445 dst = append(dst, '0') 446 } 447 } else { 448 dst = append(dst, '0') 449 } 450 451 // fraction 452 if prec > 0 { 453 dst = append(dst, '.') 454 for i := 0; i < prec; i++ { 455 ch := byte('0') 456 if j := d.dp + i; 0 <= j && j < d.nd { 457 ch = d.d[j] 458 } 459 dst = append(dst, ch) 460 } 461 } 462 463 return dst 464 } 465 466 // %b: -ddddddddp±ddd 467 func fmtB(dst []byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte { 468 // sign 469 if neg { 470 dst = append(dst, '-') 471 } 472 473 // mantissa 474 dst, _ = formatBits(dst, mant, 10, false, true) 475 476 // p 477 dst = append(dst, 'p') 478 479 // ±exponent 480 exp -= int(flt.mantbits) 481 if exp >= 0 { 482 dst = append(dst, '+') 483 } 484 dst, _ = formatBits(dst, uint64(exp), 10, exp < 0, true) 485 486 return dst 487 } 488 489 // %x: -0x1.yyyyyyyyp±ddd or -0x0p+0. (y is hex digit, d is decimal digit) 490 func fmtX(dst []byte, prec int, fmt byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte { 491 if mant == 0 { 492 exp = 0 493 } 494 495 // Shift digits so leading 1 (if any) is at bit 1<<60. 496 mant <<= 60 - flt.mantbits 497 for mant != 0 && mant&(1<<60) == 0 { 498 mant <<= 1 499 exp-- 500 } 501 502 // Round if requested. 503 if prec >= 0 && prec < 15 { 504 shift := uint(prec * 4) 505 extra := (mant << shift) & (1<<60 - 1) 506 mant >>= 60 - shift 507 if extra|(mant&1) > 1<<59 { 508 mant++ 509 } 510 mant <<= 60 - shift 511 if mant&(1<<61) != 0 { 512 // Wrapped around. 513 mant >>= 1 514 exp++ 515 } 516 } 517 518 hex := lowerhex 519 if fmt == 'X' { 520 hex = upperhex 521 } 522 523 // sign, 0x, leading digit 524 if neg { 525 dst = append(dst, '-') 526 } 527 dst = append(dst, '0', fmt, '0'+byte((mant>>60)&1)) 528 529 // .fraction 530 mant <<= 4 // remove leading 0 or 1 531 if prec < 0 && mant != 0 { 532 dst = append(dst, '.') 533 for mant != 0 { 534 dst = append(dst, hex[(mant>>60)&15]) 535 mant <<= 4 536 } 537 } else if prec > 0 { 538 dst = append(dst, '.') 539 for i := 0; i < prec; i++ { 540 dst = append(dst, hex[(mant>>60)&15]) 541 mant <<= 4 542 } 543 } 544 545 // p± 546 ch := byte('P') 547 if fmt == lower(fmt) { 548 ch = 'p' 549 } 550 dst = append(dst, ch) 551 if exp < 0 { 552 ch = '-' 553 exp = -exp 554 } else { 555 ch = '+' 556 } 557 dst = append(dst, ch) 558 559 // dd or ddd or dddd 560 switch { 561 case exp < 100: 562 dst = append(dst, byte(exp/10)+'0', byte(exp%10)+'0') 563 case exp < 1000: 564 dst = append(dst, byte(exp/100)+'0', byte((exp/10)%10)+'0', byte(exp%10)+'0') 565 default: 566 dst = append(dst, byte(exp/1000)+'0', byte(exp/100)%10+'0', byte((exp/10)%10)+'0', byte(exp%10)+'0') 567 } 568 569 return dst 570 }