github.com/sbinet/go@v0.0.0-20160827155028-54d7de7dd62b/src/math/big/floatconv_test.go (about) 1 // Copyright 2015 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 big 6 7 import ( 8 "fmt" 9 "math" 10 "strconv" 11 "testing" 12 ) 13 14 func TestFloatSetFloat64String(t *testing.T) { 15 inf := math.Inf(0) 16 nan := math.NaN() 17 18 for _, test := range []struct { 19 s string 20 x float64 // NaNs represent invalid inputs 21 }{ 22 // basics 23 {"0", 0}, 24 {"-0", -0}, 25 {"+0", 0}, 26 {"1", 1}, 27 {"-1", -1}, 28 {"+1", 1}, 29 {"1.234", 1.234}, 30 {"-1.234", -1.234}, 31 {"+1.234", 1.234}, 32 {".1", 0.1}, 33 {"1.", 1}, 34 {"+1.", 1}, 35 36 // various zeros 37 {"0e100", 0}, 38 {"-0e+100", 0}, 39 {"+0e-100", 0}, 40 {"0E100", 0}, 41 {"-0E+100", 0}, 42 {"+0E-100", 0}, 43 44 // various decimal exponent formats 45 {"1.e10", 1e10}, 46 {"1e+10", 1e10}, 47 {"+1e-10", 1e-10}, 48 {"1E10", 1e10}, 49 {"1.E+10", 1e10}, 50 {"+1E-10", 1e-10}, 51 52 // infinities 53 {"Inf", inf}, 54 {"+Inf", inf}, 55 {"-Inf", -inf}, 56 {"inf", inf}, 57 {"+inf", inf}, 58 {"-inf", -inf}, 59 60 // invalid numbers 61 {"", nan}, 62 {"-", nan}, 63 {"0x", nan}, 64 {"0e", nan}, 65 {"1.2ef", nan}, 66 {"2..3", nan}, 67 {"123..", nan}, 68 {"infinity", nan}, 69 {"foobar", nan}, 70 71 // misc decimal values 72 {"3.14159265", 3.14159265}, 73 {"-687436.79457e-245", -687436.79457e-245}, 74 {"-687436.79457E245", -687436.79457e245}, 75 {".0000000000000000000000000000000000000001", 1e-40}, 76 {"+10000000000000000000000000000000000000000e-0", 1e40}, 77 78 // decimal mantissa, binary exponent 79 {"0p0", 0}, 80 {"-0p0", -0}, 81 {"1p10", 1 << 10}, 82 {"1p+10", 1 << 10}, 83 {"+1p-10", 1.0 / (1 << 10)}, 84 {"1024p-12", 0.25}, 85 {"-1p10", -1024}, 86 {"1.5p1", 3}, 87 88 // binary mantissa, decimal exponent 89 {"0b0", 0}, 90 {"-0b0", -0}, 91 {"0b0e+10", 0}, 92 {"-0b0e-10", -0}, 93 {"0b1010", 10}, 94 {"0B1010E2", 1000}, 95 {"0b.1", 0.5}, 96 {"0b.001", 0.125}, 97 {"0b.001e3", 125}, 98 99 // binary mantissa, binary exponent 100 {"0b0p+10", 0}, 101 {"-0b0p-10", -0}, 102 {"0b.1010p4", 10}, 103 {"0b1p-1", 0.5}, 104 {"0b001p-3", 0.125}, 105 {"0b.001p3", 1}, 106 {"0b0.01p2", 1}, 107 108 // hexadecimal mantissa and exponent 109 {"0x0", 0}, 110 {"-0x0", -0}, 111 {"0x0p+10", 0}, 112 {"-0x0p-10", -0}, 113 {"0xff", 255}, 114 {"0X.8p1", 1}, 115 {"-0X0.00008p16", -0.5}, 116 {"0x0.0000000000001p-1022", math.SmallestNonzeroFloat64}, 117 {"0x1.fffffffffffffp1023", math.MaxFloat64}, 118 } { 119 var x Float 120 x.SetPrec(53) 121 _, ok := x.SetString(test.s) 122 if math.IsNaN(test.x) { 123 // test.s is invalid 124 if ok { 125 t.Errorf("%s: want parse error", test.s) 126 } 127 continue 128 } 129 // test.s is valid 130 if !ok { 131 t.Errorf("%s: got parse error", test.s) 132 continue 133 } 134 f, _ := x.Float64() 135 want := new(Float).SetFloat64(test.x) 136 if x.Cmp(want) != 0 { 137 t.Errorf("%s: got %s (%v); want %v", test.s, &x, f, test.x) 138 } 139 } 140 } 141 142 func fdiv(a, b float64) float64 { return a / b } 143 144 const ( 145 below1e23 = 99999999999999974834176 146 above1e23 = 100000000000000008388608 147 ) 148 149 func TestFloat64Text(t *testing.T) { 150 for _, test := range []struct { 151 x float64 152 format byte 153 prec int 154 want string 155 }{ 156 {0, 'f', 0, "0"}, 157 {math.Copysign(0, -1), 'f', 0, "-0"}, 158 {1, 'f', 0, "1"}, 159 {-1, 'f', 0, "-1"}, 160 161 {0.001, 'e', 0, "1e-03"}, 162 {0.459, 'e', 0, "5e-01"}, 163 {1.459, 'e', 0, "1e+00"}, 164 {2.459, 'e', 1, "2.5e+00"}, 165 {3.459, 'e', 2, "3.46e+00"}, 166 {4.459, 'e', 3, "4.459e+00"}, 167 {5.459, 'e', 4, "5.4590e+00"}, 168 169 {0.001, 'f', 0, "0"}, 170 {0.459, 'f', 0, "0"}, 171 {1.459, 'f', 0, "1"}, 172 {2.459, 'f', 1, "2.5"}, 173 {3.459, 'f', 2, "3.46"}, 174 {4.459, 'f', 3, "4.459"}, 175 {5.459, 'f', 4, "5.4590"}, 176 177 {0, 'b', 0, "0"}, 178 {math.Copysign(0, -1), 'b', 0, "-0"}, 179 {1.0, 'b', 0, "4503599627370496p-52"}, 180 {-1.0, 'b', 0, "-4503599627370496p-52"}, 181 {4503599627370496, 'b', 0, "4503599627370496p+0"}, 182 183 {0, 'p', 0, "0"}, 184 {math.Copysign(0, -1), 'p', 0, "-0"}, 185 {1024.0, 'p', 0, "0x.8p+11"}, 186 {-1024.0, 'p', 0, "-0x.8p+11"}, 187 188 // all test cases below from strconv/ftoa_test.go 189 {1, 'e', 5, "1.00000e+00"}, 190 {1, 'f', 5, "1.00000"}, 191 {1, 'g', 5, "1"}, 192 {1, 'g', -1, "1"}, 193 {20, 'g', -1, "20"}, 194 {1234567.8, 'g', -1, "1.2345678e+06"}, 195 {200000, 'g', -1, "200000"}, 196 {2000000, 'g', -1, "2e+06"}, 197 198 // g conversion and zero suppression 199 {400, 'g', 2, "4e+02"}, 200 {40, 'g', 2, "40"}, 201 {4, 'g', 2, "4"}, 202 {.4, 'g', 2, "0.4"}, 203 {.04, 'g', 2, "0.04"}, 204 {.004, 'g', 2, "0.004"}, 205 {.0004, 'g', 2, "0.0004"}, 206 {.00004, 'g', 2, "4e-05"}, 207 {.000004, 'g', 2, "4e-06"}, 208 209 {0, 'e', 5, "0.00000e+00"}, 210 {0, 'f', 5, "0.00000"}, 211 {0, 'g', 5, "0"}, 212 {0, 'g', -1, "0"}, 213 214 {-1, 'e', 5, "-1.00000e+00"}, 215 {-1, 'f', 5, "-1.00000"}, 216 {-1, 'g', 5, "-1"}, 217 {-1, 'g', -1, "-1"}, 218 219 {12, 'e', 5, "1.20000e+01"}, 220 {12, 'f', 5, "12.00000"}, 221 {12, 'g', 5, "12"}, 222 {12, 'g', -1, "12"}, 223 224 {123456700, 'e', 5, "1.23457e+08"}, 225 {123456700, 'f', 5, "123456700.00000"}, 226 {123456700, 'g', 5, "1.2346e+08"}, 227 {123456700, 'g', -1, "1.234567e+08"}, 228 229 {1.2345e6, 'e', 5, "1.23450e+06"}, 230 {1.2345e6, 'f', 5, "1234500.00000"}, 231 {1.2345e6, 'g', 5, "1.2345e+06"}, 232 233 {1e23, 'e', 17, "9.99999999999999916e+22"}, 234 {1e23, 'f', 17, "99999999999999991611392.00000000000000000"}, 235 {1e23, 'g', 17, "9.9999999999999992e+22"}, 236 237 {1e23, 'e', -1, "1e+23"}, 238 {1e23, 'f', -1, "100000000000000000000000"}, 239 {1e23, 'g', -1, "1e+23"}, 240 241 {below1e23, 'e', 17, "9.99999999999999748e+22"}, 242 {below1e23, 'f', 17, "99999999999999974834176.00000000000000000"}, 243 {below1e23, 'g', 17, "9.9999999999999975e+22"}, 244 245 {below1e23, 'e', -1, "9.999999999999997e+22"}, 246 {below1e23, 'f', -1, "99999999999999970000000"}, 247 {below1e23, 'g', -1, "9.999999999999997e+22"}, 248 249 {above1e23, 'e', 17, "1.00000000000000008e+23"}, 250 {above1e23, 'f', 17, "100000000000000008388608.00000000000000000"}, 251 {above1e23, 'g', 17, "1.0000000000000001e+23"}, 252 253 {above1e23, 'e', -1, "1.0000000000000001e+23"}, 254 {above1e23, 'f', -1, "100000000000000010000000"}, 255 {above1e23, 'g', -1, "1.0000000000000001e+23"}, 256 257 {5e-304 / 1e20, 'g', -1, "5e-324"}, 258 {-5e-304 / 1e20, 'g', -1, "-5e-324"}, 259 {fdiv(5e-304, 1e20), 'g', -1, "5e-324"}, // avoid constant arithmetic 260 {fdiv(-5e-304, 1e20), 'g', -1, "-5e-324"}, // avoid constant arithmetic 261 262 {32, 'g', -1, "32"}, 263 {32, 'g', 0, "3e+01"}, 264 265 {100, 'x', -1, "%x"}, 266 267 // {math.NaN(), 'g', -1, "NaN"}, // Float doesn't support NaNs 268 // {-math.NaN(), 'g', -1, "NaN"}, // Float doesn't support NaNs 269 {math.Inf(0), 'g', -1, "+Inf"}, 270 {math.Inf(-1), 'g', -1, "-Inf"}, 271 {-math.Inf(0), 'g', -1, "-Inf"}, 272 273 {-1, 'b', -1, "-4503599627370496p-52"}, 274 275 // fixed bugs 276 {0.9, 'f', 1, "0.9"}, 277 {0.09, 'f', 1, "0.1"}, 278 {0.0999, 'f', 1, "0.1"}, 279 {0.05, 'f', 1, "0.1"}, 280 {0.05, 'f', 0, "0"}, 281 {0.5, 'f', 1, "0.5"}, 282 {0.5, 'f', 0, "0"}, 283 {1.5, 'f', 0, "2"}, 284 285 // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/ 286 {2.2250738585072012e-308, 'g', -1, "2.2250738585072014e-308"}, 287 // http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/ 288 {2.2250738585072011e-308, 'g', -1, "2.225073858507201e-308"}, 289 290 // Issue 2625. 291 {383260575764816448, 'f', 0, "383260575764816448"}, 292 {383260575764816448, 'g', -1, "3.8326057576481645e+17"}, 293 294 // Issue 15918. 295 {1, 'f', -10, "1"}, 296 {1, 'f', -11, "1"}, 297 {1, 'f', -12, "1"}, 298 } { 299 // The test cases are from the strconv package which tests float64 values. 300 // When formatting values with prec = -1 (shortest representation), 301 // the actually available mantissa precision matters. 302 // For denormalized values, that precision is < 53 (SetFloat64 default). 303 // Compute and set the actual precision explicitly. 304 f := new(Float).SetPrec(actualPrec(test.x)).SetFloat64(test.x) 305 got := f.Text(test.format, test.prec) 306 if got != test.want { 307 t.Errorf("%v: got %s; want %s", test, got, test.want) 308 continue 309 } 310 311 if test.format == 'b' && test.x == 0 { 312 continue // 'b' format in strconv.Float requires knowledge of bias for 0.0 313 } 314 if test.format == 'p' { 315 continue // 'p' format not supported in strconv.Format 316 } 317 318 // verify that Float format matches strconv format 319 want := strconv.FormatFloat(test.x, test.format, test.prec, 64) 320 if got != want { 321 t.Errorf("%v: got %s; want %s (strconv)", test, got, want) 322 } 323 } 324 } 325 326 // actualPrec returns the number of actually used mantissa bits. 327 func actualPrec(x float64) uint { 328 if bits := math.Float64bits(x); x != 0 && bits&(0x7ff<<52) == 0 { 329 // x is denormalized 330 return 64 - nlz64(bits&(1<<52-1)) 331 } 332 return 53 333 } 334 335 func TestFloatText(t *testing.T) { 336 for _, test := range []struct { 337 x string 338 prec uint 339 format byte 340 digits int 341 want string 342 }{ 343 {"0", 10, 'f', 0, "0"}, 344 {"-0", 10, 'f', 0, "-0"}, 345 {"1", 10, 'f', 0, "1"}, 346 {"-1", 10, 'f', 0, "-1"}, 347 348 {"1.459", 100, 'e', 0, "1e+00"}, 349 {"2.459", 100, 'e', 1, "2.5e+00"}, 350 {"3.459", 100, 'e', 2, "3.46e+00"}, 351 {"4.459", 100, 'e', 3, "4.459e+00"}, 352 {"5.459", 100, 'e', 4, "5.4590e+00"}, 353 354 {"1.459", 100, 'E', 0, "1E+00"}, 355 {"2.459", 100, 'E', 1, "2.5E+00"}, 356 {"3.459", 100, 'E', 2, "3.46E+00"}, 357 {"4.459", 100, 'E', 3, "4.459E+00"}, 358 {"5.459", 100, 'E', 4, "5.4590E+00"}, 359 360 {"1.459", 100, 'f', 0, "1"}, 361 {"2.459", 100, 'f', 1, "2.5"}, 362 {"3.459", 100, 'f', 2, "3.46"}, 363 {"4.459", 100, 'f', 3, "4.459"}, 364 {"5.459", 100, 'f', 4, "5.4590"}, 365 366 {"1.459", 100, 'g', 0, "1"}, 367 {"2.459", 100, 'g', 1, "2"}, 368 {"3.459", 100, 'g', 2, "3.5"}, 369 {"4.459", 100, 'g', 3, "4.46"}, 370 {"5.459", 100, 'g', 4, "5.459"}, 371 372 {"1459", 53, 'g', 0, "1e+03"}, 373 {"2459", 53, 'g', 1, "2e+03"}, 374 {"3459", 53, 'g', 2, "3.5e+03"}, 375 {"4459", 53, 'g', 3, "4.46e+03"}, 376 {"5459", 53, 'g', 4, "5459"}, 377 378 {"1459", 53, 'G', 0, "1E+03"}, 379 {"2459", 53, 'G', 1, "2E+03"}, 380 {"3459", 53, 'G', 2, "3.5E+03"}, 381 {"4459", 53, 'G', 3, "4.46E+03"}, 382 {"5459", 53, 'G', 4, "5459"}, 383 384 {"3", 10, 'e', 40, "3.0000000000000000000000000000000000000000e+00"}, 385 {"3", 10, 'f', 40, "3.0000000000000000000000000000000000000000"}, 386 {"3", 10, 'g', 40, "3"}, 387 388 {"3e40", 100, 'e', 40, "3.0000000000000000000000000000000000000000e+40"}, 389 {"3e40", 100, 'f', 4, "30000000000000000000000000000000000000000.0000"}, 390 {"3e40", 100, 'g', 40, "3e+40"}, 391 392 // make sure "stupid" exponents don't stall the machine 393 {"1e1000000", 64, 'p', 0, "0x.88b3a28a05eade3ap+3321929"}, 394 {"1e646456992", 64, 'p', 0, "0x.e883a0c5c8c7c42ap+2147483644"}, 395 {"1e646456993", 64, 'p', 0, "+Inf"}, 396 {"1e1000000000", 64, 'p', 0, "+Inf"}, 397 {"1e-1000000", 64, 'p', 0, "0x.efb4542cc8ca418ap-3321928"}, 398 {"1e-646456993", 64, 'p', 0, "0x.e17c8956983d9d59p-2147483647"}, 399 {"1e-646456994", 64, 'p', 0, "0"}, 400 {"1e-1000000000", 64, 'p', 0, "0"}, 401 402 // minimum and maximum values 403 {"1p2147483646", 64, 'p', 0, "0x.8p+2147483647"}, 404 {"0x.8p2147483647", 64, 'p', 0, "0x.8p+2147483647"}, 405 {"0x.8p-2147483647", 64, 'p', 0, "0x.8p-2147483647"}, 406 {"1p-2147483649", 64, 'p', 0, "0x.8p-2147483648"}, 407 408 // TODO(gri) need tests for actual large Floats 409 410 {"0", 53, 'b', 0, "0"}, 411 {"-0", 53, 'b', 0, "-0"}, 412 {"1.0", 53, 'b', 0, "4503599627370496p-52"}, 413 {"-1.0", 53, 'b', 0, "-4503599627370496p-52"}, 414 {"4503599627370496", 53, 'b', 0, "4503599627370496p+0"}, 415 416 // issue 9939 417 {"3", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"}, 418 {"03", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"}, 419 {"3.", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"}, 420 {"3.0", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"}, 421 {"3.00", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"}, 422 {"3.000", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"}, 423 424 {"3", 350, 'p', 0, "0x.cp+2"}, 425 {"03", 350, 'p', 0, "0x.cp+2"}, 426 {"3.", 350, 'p', 0, "0x.cp+2"}, 427 {"3.0", 350, 'p', 0, "0x.cp+2"}, 428 {"3.00", 350, 'p', 0, "0x.cp+2"}, 429 {"3.000", 350, 'p', 0, "0x.cp+2"}, 430 431 {"0", 64, 'p', 0, "0"}, 432 {"-0", 64, 'p', 0, "-0"}, 433 {"1024.0", 64, 'p', 0, "0x.8p+11"}, 434 {"-1024.0", 64, 'p', 0, "-0x.8p+11"}, 435 436 // unsupported format 437 {"3.14", 64, 'x', 0, "%x"}, 438 {"-3.14", 64, 'x', 0, "%x"}, 439 } { 440 f, _, err := ParseFloat(test.x, 0, test.prec, ToNearestEven) 441 if err != nil { 442 t.Errorf("%v: %s", test, err) 443 continue 444 } 445 446 got := f.Text(test.format, test.digits) 447 if got != test.want { 448 t.Errorf("%v: got %s; want %s", test, got, test.want) 449 } 450 451 // compare with strconv.FormatFloat output if possible 452 // ('p' format is not supported by strconv.FormatFloat, 453 // and its output for 0.0 prints a biased exponent value 454 // as in 0p-1074 which makes no sense to emulate here) 455 if test.prec == 53 && test.format != 'p' && f.Sign() != 0 { 456 f64, acc := f.Float64() 457 if acc != Exact { 458 t.Errorf("%v: expected exact conversion to float64", test) 459 continue 460 } 461 got := strconv.FormatFloat(f64, test.format, test.digits, 64) 462 if got != test.want { 463 t.Errorf("%v: got %s; want %s", test, got, test.want) 464 } 465 } 466 } 467 } 468 469 func TestFloatFormat(t *testing.T) { 470 for _, test := range []struct { 471 format string 472 value interface{} // float32, float64, or string (== 512bit *Float) 473 want string 474 }{ 475 // from fmt/fmt_test.go 476 {"%+.3e", 0.0, "+0.000e+00"}, 477 {"%+.3e", 1.0, "+1.000e+00"}, 478 {"%+.3f", -1.0, "-1.000"}, 479 {"%+.3F", -1.0, "-1.000"}, 480 {"%+.3F", float32(-1.0), "-1.000"}, 481 {"%+07.2f", 1.0, "+001.00"}, 482 {"%+07.2f", -1.0, "-001.00"}, 483 {"%+10.2f", +1.0, " +1.00"}, 484 {"%+10.2f", -1.0, " -1.00"}, 485 {"% .3E", -1.0, "-1.000E+00"}, 486 {"% .3e", 1.0, " 1.000e+00"}, 487 {"%+.3g", 0.0, "+0"}, 488 {"%+.3g", 1.0, "+1"}, 489 {"%+.3g", -1.0, "-1"}, 490 {"% .3g", -1.0, "-1"}, 491 {"% .3g", 1.0, " 1"}, 492 {"%b", float32(1.0), "8388608p-23"}, 493 {"%b", 1.0, "4503599627370496p-52"}, 494 495 // from fmt/fmt_test.go: old test/fmt_test.go 496 {"%e", 1.0, "1.000000e+00"}, 497 {"%e", 1234.5678e3, "1.234568e+06"}, 498 {"%e", 1234.5678e-8, "1.234568e-05"}, 499 {"%e", -7.0, "-7.000000e+00"}, 500 {"%e", -1e-9, "-1.000000e-09"}, 501 {"%f", 1234.5678e3, "1234567.800000"}, 502 {"%f", 1234.5678e-8, "0.000012"}, 503 {"%f", -7.0, "-7.000000"}, 504 {"%f", -1e-9, "-0.000000"}, 505 {"%g", 1234.5678e3, "1.2345678e+06"}, 506 {"%g", float32(1234.5678e3), "1.2345678e+06"}, 507 {"%g", 1234.5678e-8, "1.2345678e-05"}, 508 {"%g", -7.0, "-7"}, 509 {"%g", -1e-9, "-1e-09"}, 510 {"%g", float32(-1e-9), "-1e-09"}, 511 {"%E", 1.0, "1.000000E+00"}, 512 {"%E", 1234.5678e3, "1.234568E+06"}, 513 {"%E", 1234.5678e-8, "1.234568E-05"}, 514 {"%E", -7.0, "-7.000000E+00"}, 515 {"%E", -1e-9, "-1.000000E-09"}, 516 {"%G", 1234.5678e3, "1.2345678E+06"}, 517 {"%G", float32(1234.5678e3), "1.2345678E+06"}, 518 {"%G", 1234.5678e-8, "1.2345678E-05"}, 519 {"%G", -7.0, "-7"}, 520 {"%G", -1e-9, "-1E-09"}, 521 {"%G", float32(-1e-9), "-1E-09"}, 522 523 {"%20.6e", 1.2345e3, " 1.234500e+03"}, 524 {"%20.6e", 1.2345e-3, " 1.234500e-03"}, 525 {"%20e", 1.2345e3, " 1.234500e+03"}, 526 {"%20e", 1.2345e-3, " 1.234500e-03"}, 527 {"%20.8e", 1.2345e3, " 1.23450000e+03"}, 528 {"%20f", 1.23456789e3, " 1234.567890"}, 529 {"%20f", 1.23456789e-3, " 0.001235"}, 530 {"%20f", 12345678901.23456789, " 12345678901.234568"}, 531 {"%-20f", 1.23456789e3, "1234.567890 "}, 532 {"%20.8f", 1.23456789e3, " 1234.56789000"}, 533 {"%20.8f", 1.23456789e-3, " 0.00123457"}, 534 {"%g", 1.23456789e3, "1234.56789"}, 535 {"%g", 1.23456789e-3, "0.00123456789"}, 536 {"%g", 1.23456789e20, "1.23456789e+20"}, 537 {"%20e", math.Inf(1), " +Inf"}, 538 {"%-20f", math.Inf(-1), "-Inf "}, 539 540 // from fmt/fmt_test.go: comparison of padding rules with C printf 541 {"%.2f", 1.0, "1.00"}, 542 {"%.2f", -1.0, "-1.00"}, 543 {"% .2f", 1.0, " 1.00"}, 544 {"% .2f", -1.0, "-1.00"}, 545 {"%+.2f", 1.0, "+1.00"}, 546 {"%+.2f", -1.0, "-1.00"}, 547 {"%7.2f", 1.0, " 1.00"}, 548 {"%7.2f", -1.0, " -1.00"}, 549 {"% 7.2f", 1.0, " 1.00"}, 550 {"% 7.2f", -1.0, " -1.00"}, 551 {"%+7.2f", 1.0, " +1.00"}, 552 {"%+7.2f", -1.0, " -1.00"}, 553 {"%07.2f", 1.0, "0001.00"}, 554 {"%07.2f", -1.0, "-001.00"}, 555 {"% 07.2f", 1.0, " 001.00"}, 556 {"% 07.2f", -1.0, "-001.00"}, 557 {"%+07.2f", 1.0, "+001.00"}, 558 {"%+07.2f", -1.0, "-001.00"}, 559 560 // from fmt/fmt_test.go: zero padding does not apply to infinities 561 {"%020f", math.Inf(-1), " -Inf"}, 562 {"%020f", math.Inf(+1), " +Inf"}, 563 {"% 020f", math.Inf(-1), " -Inf"}, 564 {"% 020f", math.Inf(+1), " Inf"}, 565 {"%+020f", math.Inf(-1), " -Inf"}, 566 {"%+020f", math.Inf(+1), " +Inf"}, 567 {"%20f", -1.0, " -1.000000"}, 568 569 // handle %v like %g 570 {"%v", 0.0, "0"}, 571 {"%v", -7.0, "-7"}, 572 {"%v", -1e-9, "-1e-09"}, 573 {"%v", float32(-1e-9), "-1e-09"}, 574 {"%010v", 0.0, "0000000000"}, 575 576 // *Float cases 577 {"%.20f", "1e-20", "0.00000000000000000001"}, 578 {"%.20f", "-1e-20", "-0.00000000000000000001"}, 579 {"%30.20f", "-1e-20", " -0.00000000000000000001"}, 580 {"%030.20f", "-1e-20", "-00000000.00000000000000000001"}, 581 {"%030.20f", "+1e-20", "000000000.00000000000000000001"}, 582 {"% 030.20f", "+1e-20", " 00000000.00000000000000000001"}, 583 584 // erroneous formats 585 {"%s", 1.0, "%!s(*big.Float=1)"}, 586 } { 587 value := new(Float) 588 switch v := test.value.(type) { 589 case float32: 590 value.SetPrec(24).SetFloat64(float64(v)) 591 case float64: 592 value.SetPrec(53).SetFloat64(v) 593 case string: 594 value.SetPrec(512).Parse(v, 0) 595 default: 596 t.Fatalf("unsupported test value: %v (%T)", v, v) 597 } 598 599 if got := fmt.Sprintf(test.format, value); got != test.want { 600 t.Errorf("%v: got %q; want %q", test, got, test.want) 601 } 602 } 603 } 604 605 func BenchmarkParseFloatSmallExp(b *testing.B) { 606 for i := 0; i < b.N; i++ { 607 for _, s := range []string{ 608 "1e0", 609 "1e-1", 610 "1e-2", 611 "1e-3", 612 "1e-4", 613 "1e-5", 614 "1e-10", 615 "1e-20", 616 "1e-50", 617 "1e1", 618 "1e2", 619 "1e3", 620 "1e4", 621 "1e5", 622 "1e10", 623 "1e20", 624 "1e50", 625 } { 626 var x Float 627 _, _, err := x.Parse(s, 0) 628 if err != nil { 629 b.Fatalf("%s: %v", s, err) 630 } 631 } 632 } 633 } 634 635 func BenchmarkParseFloatLargeExp(b *testing.B) { 636 for i := 0; i < b.N; i++ { 637 for _, s := range []string{ 638 "1e0", 639 "1e-10", 640 "1e-20", 641 "1e-30", 642 "1e-40", 643 "1e-50", 644 "1e-100", 645 "1e-500", 646 "1e-1000", 647 "1e-5000", 648 "1e-10000", 649 "1e10", 650 "1e20", 651 "1e30", 652 "1e40", 653 "1e50", 654 "1e100", 655 "1e500", 656 "1e1000", 657 "1e5000", 658 "1e10000", 659 } { 660 var x Float 661 _, _, err := x.Parse(s, 0) 662 if err != nil { 663 b.Fatalf("%s: %v", s, err) 664 } 665 } 666 } 667 }