Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
floatconv_test.go826 linesDownload Raw Back to big
1// Copyright 2015 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.4 5package big6 7import (8	"bytes"9	"fmt"10	"math"11	"math/bits"12	"strconv"13	"testing"14)15 16var zero_ float6417 18func TestFloatSetFloat64String(t *testing.T) {19	inf := math.Inf(0)20	nan := math.NaN()21 22	for _, test := range []struct {23		s string24		x float64 // NaNs represent invalid inputs25	}{26		// basics27		{"0", 0},28		{"-0", -zero_},29		{"+0", 0},30		{"1", 1},31		{"-1", -1},32		{"+1", 1},33		{"1.234", 1.234},34		{"-1.234", -1.234},35		{"+1.234", 1.234},36		{".1", 0.1},37		{"1.", 1},38		{"+1.", 1},39 40		// various zeros41		{"0e100", 0},42		{"-0e+100", -zero_},43		{"+0e-100", 0},44		{"0E100", 0},45		{"-0E+100", -zero_},46		{"+0E-100", 0},47 48		// various decimal exponent formats49		{"1.e10", 1e10},50		{"1e+10", 1e10},51		{"+1e-10", 1e-10},52		{"1E10", 1e10},53		{"1.E+10", 1e10},54		{"+1E-10", 1e-10},55 56		// infinities57		{"Inf", inf},58		{"+Inf", inf},59		{"-Inf", -inf},60		{"inf", inf},61		{"+inf", inf},62		{"-inf", -inf},63 64		// invalid numbers65		{"", nan},66		{"-", nan},67		{"0x", nan},68		{"0e", nan},69		{"1.2ef", nan},70		{"2..3", nan},71		{"123..", nan},72		{"infinity", nan},73		{"foobar", nan},74 75		// invalid underscores76		{"_", nan},77		{"0_", nan},78		{"1__0", nan},79		{"123_.", nan},80		{"123._", nan},81		{"123._4", nan},82		{"1_2.3_4_", nan},83		{"_.123", nan},84		{"_123.456", nan},85		{"10._0", nan},86		{"10.0e_0", nan},87		{"10.0e0_", nan},88		{"0P-0__0", nan},89 90		// misc decimal values91		{"3.14159265", 3.14159265},92		{"-687436.79457e-245", -687436.79457e-245},93		{"-687436.79457E245", -687436.79457e245},94		{".0000000000000000000000000000000000000001", 1e-40},95		{"+10000000000000000000000000000000000000000e-0", 1e40},96 97		// decimal mantissa, binary exponent98		{"0p0", 0},99		{"-0p0", -zero_},100		{"1p10", 1 << 10},101		{"1p+10", 1 << 10},102		{"+1p-10", 1.0 / (1 << 10)},103		{"1024p-12", 0.25},104		{"-1p10", -1024},105		{"1.5p1", 3},106 107		// binary mantissa, decimal exponent108		{"0b0", 0},109		{"-0b0", -zero_},110		{"0b0e+10", 0},111		{"-0b0e-10", -zero_},112		{"0b1010", 10},113		{"0B1010E2", 1000},114		{"0b.1", 0.5},115		{"0b.001", 0.125},116		{"0b.001e3", 125},117 118		// binary mantissa, binary exponent119		{"0b0p+10", 0},120		{"-0b0p-10", -zero_},121		{"0b.1010p4", 10},122		{"0b1p-1", 0.5},123		{"0b001p-3", 0.125},124		{"0b.001p3", 1},125		{"0b0.01p2", 1},126		{"0b0.01P+2", 1},127 128		// octal mantissa, decimal exponent129		{"0o0", 0},130		{"-0o0", -zero_},131		{"0o0e+10", 0},132		{"-0o0e-10", -zero_},133		{"0o12", 10},134		{"0O12E2", 1000},135		{"0o.4", 0.5},136		{"0o.01", 0.015625},137		{"0o.01e3", 15.625},138 139		// octal mantissa, binary exponent140		{"0o0p+10", 0},141		{"-0o0p-10", -zero_},142		{"0o.12p6", 10},143		{"0o4p-3", 0.5},144		{"0o0014p-6", 0.1875},145		{"0o.001p9", 1},146		{"0o0.01p7", 2},147		{"0O0.01P+2", 0.0625},148 149		// hexadecimal mantissa and exponent150		{"0x0", 0},151		{"-0x0", -zero_},152		{"0x0p+10", 0},153		{"-0x0p-10", -zero_},154		{"0xff", 255},155		{"0X.8p1", 1},156		{"-0X0.00008p16", -0.5},157		{"-0X0.00008P+16", -0.5},158		{"0x0.0000000000001p-1022", math.SmallestNonzeroFloat64},159		{"0x1.fffffffffffffp1023", math.MaxFloat64},160 161		// underscores162		{"0_0", 0},163		{"1_000.", 1000},164		{"1_2_3.4_5_6", 123.456},165		{"1.0e0_0", 1},166		{"1p+1_0", 1024},167		{"0b_1000", 0x8},168		{"0b_1011_1101", 0xbd},169		{"0x_f0_0d_1eP+0_8", 0xf00d1e00},170	} {171		var x Float172		x.SetPrec(53)173		_, ok := x.SetString(test.s)174		if math.IsNaN(test.x) {175			// test.s is invalid176			if ok {177				t.Errorf("%s: want parse error", test.s)178			}179			continue180		}181		// test.s is valid182		if !ok {183			t.Errorf("%s: got parse error", test.s)184			continue185		}186		f, _ := x.Float64()187		want := new(Float).SetFloat64(test.x)188		if x.Cmp(want) != 0 || x.Signbit() != want.Signbit() {189			t.Errorf("%s: got %v (%v); want %v", test.s, &x, f, test.x)190		}191	}192}193 194func fdiv(a, b float64) float64 { return a / b }195 196const (197	below1e23 = 99999999999999974834176198	above1e23 = 100000000000000008388608199)200 201func TestFloat64Text(t *testing.T) {202	for _, test := range []struct {203		x      float64204		format byte205		prec   int206		want   string207	}{208		{0, 'f', 0, "0"},209		{math.Copysign(0, -1), 'f', 0, "-0"},210		{1, 'f', 0, "1"},211		{-1, 'f', 0, "-1"},212 213		{0.001, 'e', 0, "1e-03"},214		{0.459, 'e', 0, "5e-01"},215		{1.459, 'e', 0, "1e+00"},216		{2.459, 'e', 1, "2.5e+00"},217		{3.459, 'e', 2, "3.46e+00"},218		{4.459, 'e', 3, "4.459e+00"},219		{5.459, 'e', 4, "5.4590e+00"},220 221		{0.001, 'f', 0, "0"},222		{0.459, 'f', 0, "0"},223		{1.459, 'f', 0, "1"},224		{2.459, 'f', 1, "2.5"},225		{3.459, 'f', 2, "3.46"},226		{4.459, 'f', 3, "4.459"},227		{5.459, 'f', 4, "5.4590"},228 229		{0, 'b', 0, "0"},230		{math.Copysign(0, -1), 'b', 0, "-0"},231		{1.0, 'b', 0, "4503599627370496p-52"},232		{-1.0, 'b', 0, "-4503599627370496p-52"},233		{4503599627370496, 'b', 0, "4503599627370496p+0"},234 235		{0, 'p', 0, "0"},236		{math.Copysign(0, -1), 'p', 0, "-0"},237		{1024.0, 'p', 0, "0x.8p+11"},238		{-1024.0, 'p', 0, "-0x.8p+11"},239 240		// all test cases below from strconv/ftoa_test.go241		{1, 'e', 5, "1.00000e+00"},242		{1, 'f', 5, "1.00000"},243		{1, 'g', 5, "1"},244		{1, 'g', -1, "1"},245		{20, 'g', -1, "20"},246		{1234567.8, 'g', -1, "1.2345678e+06"},247		{200000, 'g', -1, "200000"},248		{2000000, 'g', -1, "2e+06"},249 250		// g conversion and zero suppression251		{400, 'g', 2, "4e+02"},252		{40, 'g', 2, "40"},253		{4, 'g', 2, "4"},254		{.4, 'g', 2, "0.4"},255		{.04, 'g', 2, "0.04"},256		{.004, 'g', 2, "0.004"},257		{.0004, 'g', 2, "0.0004"},258		{.00004, 'g', 2, "4e-05"},259		{.000004, 'g', 2, "4e-06"},260 261		{0, 'e', 5, "0.00000e+00"},262		{0, 'f', 5, "0.00000"},263		{0, 'g', 5, "0"},264		{0, 'g', -1, "0"},265 266		{-1, 'e', 5, "-1.00000e+00"},267		{-1, 'f', 5, "-1.00000"},268		{-1, 'g', 5, "-1"},269		{-1, 'g', -1, "-1"},270 271		{12, 'e', 5, "1.20000e+01"},272		{12, 'f', 5, "12.00000"},273		{12, 'g', 5, "12"},274		{12, 'g', -1, "12"},275 276		{123456700, 'e', 5, "1.23457e+08"},277		{123456700, 'f', 5, "123456700.00000"},278		{123456700, 'g', 5, "1.2346e+08"},279		{123456700, 'g', -1, "1.234567e+08"},280 281		{1.2345e6, 'e', 5, "1.23450e+06"},282		{1.2345e6, 'f', 5, "1234500.00000"},283		{1.2345e6, 'g', 5, "1.2345e+06"},284 285		{1e23, 'e', 17, "9.99999999999999916e+22"},286		{1e23, 'f', 17, "99999999999999991611392.00000000000000000"},287		{1e23, 'g', 17, "9.9999999999999992e+22"},288 289		{1e23, 'e', -1, "1e+23"},290		{1e23, 'f', -1, "100000000000000000000000"},291		{1e23, 'g', -1, "1e+23"},292 293		{below1e23, 'e', 17, "9.99999999999999748e+22"},294		{below1e23, 'f', 17, "99999999999999974834176.00000000000000000"},295		{below1e23, 'g', 17, "9.9999999999999975e+22"},296 297		{below1e23, 'e', -1, "9.999999999999997e+22"},298		{below1e23, 'f', -1, "99999999999999970000000"},299		{below1e23, 'g', -1, "9.999999999999997e+22"},300 301		{above1e23, 'e', 17, "1.00000000000000008e+23"},302		{above1e23, 'f', 17, "100000000000000008388608.00000000000000000"},303		{above1e23, 'g', 17, "1.0000000000000001e+23"},304 305		{above1e23, 'e', -1, "1.0000000000000001e+23"},306		{above1e23, 'f', -1, "100000000000000010000000"},307		{above1e23, 'g', -1, "1.0000000000000001e+23"},308 309		{5e-304 / 1e20, 'g', -1, "5e-324"},310		{-5e-304 / 1e20, 'g', -1, "-5e-324"},311		{fdiv(5e-304, 1e20), 'g', -1, "5e-324"},   // avoid constant arithmetic312		{fdiv(-5e-304, 1e20), 'g', -1, "-5e-324"}, // avoid constant arithmetic313 314		{32, 'g', -1, "32"},315		{32, 'g', 0, "3e+01"},316 317		{100, 'x', -1, "0x1.9p+06"},318 319		// {math.NaN(), 'g', -1, "NaN"},  // Float doesn't support NaNs320		// {-math.NaN(), 'g', -1, "NaN"}, // Float doesn't support NaNs321		{math.Inf(0), 'g', -1, "+Inf"},322		{math.Inf(-1), 'g', -1, "-Inf"},323		{-math.Inf(0), 'g', -1, "-Inf"},324 325		{-1, 'b', -1, "-4503599627370496p-52"},326 327		// fixed bugs328		{0.9, 'f', 1, "0.9"},329		{0.09, 'f', 1, "0.1"},330		{0.0999, 'f', 1, "0.1"},331		{0.05, 'f', 1, "0.1"},332		{0.05, 'f', 0, "0"},333		{0.5, 'f', 1, "0.5"},334		{0.5, 'f', 0, "0"},335		{1.5, 'f', 0, "2"},336 337		// https://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/338		{2.2250738585072012e-308, 'g', -1, "2.2250738585072014e-308"},339		// https://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/340		{2.2250738585072011e-308, 'g', -1, "2.225073858507201e-308"},341 342		// Issue 2625.343		{383260575764816448, 'f', 0, "383260575764816448"},344		{383260575764816448, 'g', -1, "3.8326057576481645e+17"},345 346		// Issue 15918.347		{1, 'f', -10, "1"},348		{1, 'f', -11, "1"},349		{1, 'f', -12, "1"},350	} {351		// The test cases are from the strconv package which tests float64 values.352		// When formatting values with prec = -1 (shortest representation),353		// the actually available mantissa precision matters.354		// For denormalized values, that precision is < 53 (SetFloat64 default).355		// Compute and set the actual precision explicitly.356		f := new(Float).SetPrec(actualPrec(test.x)).SetFloat64(test.x)357		got := f.Text(test.format, test.prec)358		if got != test.want {359			t.Errorf("%v: got %s; want %s", test, got, test.want)360			continue361		}362 363		if test.format == 'b' && test.x == 0 {364			continue // 'b' format in strconv.Float requires knowledge of bias for 0.0365		}366		if test.format == 'p' {367			continue // 'p' format not supported in strconv.Format368		}369 370		// verify that Float format matches strconv format371		want := strconv.FormatFloat(test.x, test.format, test.prec, 64)372		if got != want {373			t.Errorf("%v: got %s; want %s (strconv)", test, got, want)374		}375	}376}377 378// actualPrec returns the number of actually used mantissa bits.379func actualPrec(x float64) uint {380	if mant := math.Float64bits(x); x != 0 && mant&(0x7ff<<52) == 0 {381		// x is denormalized382		return 64 - uint(bits.LeadingZeros64(mant&(1<<52-1)))383	}384	return 53385}386 387func TestFloatText(t *testing.T) {388	const defaultRound = ^RoundingMode(0)389 390	for _, test := range []struct {391		x      string392		round  RoundingMode393		prec   uint394		format byte395		digits int396		want   string397	}{398		{"0", defaultRound, 10, 'f', 0, "0"},399		{"-0", defaultRound, 10, 'f', 0, "-0"},400		{"1", defaultRound, 10, 'f', 0, "1"},401		{"-1", defaultRound, 10, 'f', 0, "-1"},402 403		{"1.459", defaultRound, 100, 'e', 0, "1e+00"},404		{"2.459", defaultRound, 100, 'e', 1, "2.5e+00"},405		{"3.459", defaultRound, 100, 'e', 2, "3.46e+00"},406		{"4.459", defaultRound, 100, 'e', 3, "4.459e+00"},407		{"5.459", defaultRound, 100, 'e', 4, "5.4590e+00"},408 409		{"1.459", defaultRound, 100, 'E', 0, "1E+00"},410		{"2.459", defaultRound, 100, 'E', 1, "2.5E+00"},411		{"3.459", defaultRound, 100, 'E', 2, "3.46E+00"},412		{"4.459", defaultRound, 100, 'E', 3, "4.459E+00"},413		{"5.459", defaultRound, 100, 'E', 4, "5.4590E+00"},414 415		{"1.459", defaultRound, 100, 'f', 0, "1"},416		{"2.459", defaultRound, 100, 'f', 1, "2.5"},417		{"3.459", defaultRound, 100, 'f', 2, "3.46"},418		{"4.459", defaultRound, 100, 'f', 3, "4.459"},419		{"5.459", defaultRound, 100, 'f', 4, "5.4590"},420 421		{"1.459", defaultRound, 100, 'g', 0, "1"},422		{"2.459", defaultRound, 100, 'g', 1, "2"},423		{"3.459", defaultRound, 100, 'g', 2, "3.5"},424		{"4.459", defaultRound, 100, 'g', 3, "4.46"},425		{"5.459", defaultRound, 100, 'g', 4, "5.459"},426 427		{"1459", defaultRound, 53, 'g', 0, "1e+03"},428		{"2459", defaultRound, 53, 'g', 1, "2e+03"},429		{"3459", defaultRound, 53, 'g', 2, "3.5e+03"},430		{"4459", defaultRound, 53, 'g', 3, "4.46e+03"},431		{"5459", defaultRound, 53, 'g', 4, "5459"},432 433		{"1459", defaultRound, 53, 'G', 0, "1E+03"},434		{"2459", defaultRound, 53, 'G', 1, "2E+03"},435		{"3459", defaultRound, 53, 'G', 2, "3.5E+03"},436		{"4459", defaultRound, 53, 'G', 3, "4.46E+03"},437		{"5459", defaultRound, 53, 'G', 4, "5459"},438 439		{"3", defaultRound, 10, 'e', 40, "3.0000000000000000000000000000000000000000e+00"},440		{"3", defaultRound, 10, 'f', 40, "3.0000000000000000000000000000000000000000"},441		{"3", defaultRound, 10, 'g', 40, "3"},442 443		{"3e40", defaultRound, 100, 'e', 40, "3.0000000000000000000000000000000000000000e+40"},444		{"3e40", defaultRound, 100, 'f', 4, "30000000000000000000000000000000000000000.0000"},445		{"3e40", defaultRound, 100, 'g', 40, "3e+40"},446 447		// make sure "stupid" exponents don't stall the machine448		{"1e1000000", defaultRound, 64, 'p', 0, "0x.88b3a28a05eade3ap+3321929"},449		{"1e646456992", defaultRound, 64, 'p', 0, "0x.e883a0c5c8c7c42ap+2147483644"},450		{"1e646456993", defaultRound, 64, 'p', 0, "+Inf"},451		{"1e1000000000", defaultRound, 64, 'p', 0, "+Inf"},452		{"1e-1000000", defaultRound, 64, 'p', 0, "0x.efb4542cc8ca418ap-3321928"},453		{"1e-646456993", defaultRound, 64, 'p', 0, "0x.e17c8956983d9d59p-2147483647"},454		{"1e-646456994", defaultRound, 64, 'p', 0, "0"},455		{"1e-1000000000", defaultRound, 64, 'p', 0, "0"},456 457		// minimum and maximum values458		{"1p2147483646", defaultRound, 64, 'p', 0, "0x.8p+2147483647"},459		{"0x.8p2147483647", defaultRound, 64, 'p', 0, "0x.8p+2147483647"},460		{"0x.8p-2147483647", defaultRound, 64, 'p', 0, "0x.8p-2147483647"},461		{"1p-2147483649", defaultRound, 64, 'p', 0, "0x.8p-2147483648"},462 463		// TODO(gri) need tests for actual large Floats464 465		{"0", defaultRound, 53, 'b', 0, "0"},466		{"-0", defaultRound, 53, 'b', 0, "-0"},467		{"1.0", defaultRound, 53, 'b', 0, "4503599627370496p-52"},468		{"-1.0", defaultRound, 53, 'b', 0, "-4503599627370496p-52"},469		{"4503599627370496", defaultRound, 53, 'b', 0, "4503599627370496p+0"},470 471		// issue 9939472		{"3", defaultRound, 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"},473		{"03", defaultRound, 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"},474		{"3.", defaultRound, 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"},475		{"3.0", defaultRound, 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"},476		{"3.00", defaultRound, 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"},477		{"3.000", defaultRound, 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"},478 479		{"3", defaultRound, 350, 'p', 0, "0x.cp+2"},480		{"03", defaultRound, 350, 'p', 0, "0x.cp+2"},481		{"3.", defaultRound, 350, 'p', 0, "0x.cp+2"},482		{"3.0", defaultRound, 350, 'p', 0, "0x.cp+2"},483		{"3.00", defaultRound, 350, 'p', 0, "0x.cp+2"},484		{"3.000", defaultRound, 350, 'p', 0, "0x.cp+2"},485 486		{"0", defaultRound, 64, 'p', 0, "0"},487		{"-0", defaultRound, 64, 'p', 0, "-0"},488		{"1024.0", defaultRound, 64, 'p', 0, "0x.8p+11"},489		{"-1024.0", defaultRound, 64, 'p', 0, "-0x.8p+11"},490 491		{"0", defaultRound, 64, 'x', -1, "0x0p+00"},492		{"0", defaultRound, 64, 'x', 0, "0x0p+00"},493		{"0", defaultRound, 64, 'x', 1, "0x0.0p+00"},494		{"0", defaultRound, 64, 'x', 5, "0x0.00000p+00"},495		{"3.25", defaultRound, 64, 'x', 0, "0x1p+02"},496		{"-3.25", defaultRound, 64, 'x', 0, "-0x1p+02"},497		{"3.25", defaultRound, 64, 'x', 1, "0x1.ap+01"},498		{"-3.25", defaultRound, 64, 'x', 1, "-0x1.ap+01"},499		{"3.25", defaultRound, 64, 'x', -1, "0x1.ap+01"},500		{"-3.25", defaultRound, 64, 'x', -1, "-0x1.ap+01"},501		{"1024.0", defaultRound, 64, 'x', 0, "0x1p+10"},502		{"-1024.0", defaultRound, 64, 'x', 0, "-0x1p+10"},503		{"1024.0", defaultRound, 64, 'x', 5, "0x1.00000p+10"},504		{"8191.0", defaultRound, 53, 'x', -1, "0x1.fffp+12"},505		{"8191.5", defaultRound, 53, 'x', -1, "0x1.fff8p+12"},506		{"8191.53125", defaultRound, 53, 'x', -1, "0x1.fff88p+12"},507		{"8191.53125", defaultRound, 53, 'x', 4, "0x1.fff8p+12"},508		{"8191.53125", defaultRound, 53, 'x', 3, "0x1.000p+13"},509		{"8191.53125", defaultRound, 53, 'x', 0, "0x1p+13"},510		{"8191.533203125", defaultRound, 53, 'x', -1, "0x1.fff888p+12"},511		{"8191.533203125", defaultRound, 53, 'x', 5, "0x1.fff88p+12"},512		{"8191.533203125", defaultRound, 53, 'x', 4, "0x1.fff9p+12"},513 514		{"8191.53125", defaultRound, 53, 'x', -1, "0x1.fff88p+12"},515		{"8191.53125", ToNearestEven, 53, 'x', 5, "0x1.fff88p+12"},516		{"8191.53125", ToNearestAway, 53, 'x', 5, "0x1.fff88p+12"},517		{"8191.53125", ToZero, 53, 'x', 5, "0x1.fff88p+12"},518		{"8191.53125", AwayFromZero, 53, 'x', 5, "0x1.fff88p+12"},519		{"8191.53125", ToNegativeInf, 53, 'x', 5, "0x1.fff88p+12"},520		{"8191.53125", ToPositiveInf, 53, 'x', 5, "0x1.fff88p+12"},521 522		{"8191.53125", defaultRound, 53, 'x', 4, "0x1.fff8p+12"},523		{"8191.53125", defaultRound, 53, 'x', 3, "0x1.000p+13"},524		{"8191.53125", defaultRound, 53, 'x', 0, "0x1p+13"},525		{"8191.533203125", defaultRound, 53, 'x', -1, "0x1.fff888p+12"},526		{"8191.533203125", defaultRound, 53, 'x', 6, "0x1.fff888p+12"},527		{"8191.533203125", defaultRound, 53, 'x', 5, "0x1.fff88p+12"},528		{"8191.533203125", defaultRound, 53, 'x', 4, "0x1.fff9p+12"},529 530		{"8191.53125", ToNearestEven, 53, 'x', 4, "0x1.fff8p+12"},531		{"8191.53125", ToNearestAway, 53, 'x', 4, "0x1.fff9p+12"},532		{"8191.53125", ToZero, 53, 'x', 4, "0x1.fff8p+12"},533		{"8191.53125", ToZero, 53, 'x', 2, "0x1.ffp+12"},534		{"8191.53125", AwayFromZero, 53, 'x', 4, "0x1.fff9p+12"},535		{"8191.53125", ToNegativeInf, 53, 'x', 4, "0x1.fff8p+12"},536		{"-8191.53125", ToNegativeInf, 53, 'x', 4, "-0x1.fff9p+12"},537		{"8191.53125", ToPositiveInf, 53, 'x', 4, "0x1.fff9p+12"},538		{"-8191.53125", ToPositiveInf, 53, 'x', 4, "-0x1.fff8p+12"},539 540		// issue 34343541		{"0x.8p-2147483648", ToNearestEven, 4, 'p', -1, "0x.8p-2147483648"},542		{"0x.8p-2147483648", ToNearestEven, 4, 'x', -1, "0x1p-2147483649"},543	} {544		f, _, err := ParseFloat(test.x, 0, test.prec, ToNearestEven)545		if err != nil {546			t.Errorf("%v: %s", test, err)547			continue548		}549		if test.round != defaultRound {550			f.SetMode(test.round)551		}552 553		got := f.Text(test.format, test.digits)554		if got != test.want {555			t.Errorf("%v: got %s; want %s", test, got, test.want)556		}557 558		// compare with strconv.FormatFloat output if possible559		// ('p' format is not supported by strconv.FormatFloat,560		// and its output for 0.0 prints a biased exponent value561		// as in 0p-1074 which makes no sense to emulate here)562		if test.prec == 53 && test.format != 'p' && f.Sign() != 0 && (test.round == ToNearestEven || test.round == defaultRound) {563			f64, acc := f.Float64()564			if acc != Exact {565				t.Errorf("%v: expected exact conversion to float64", test)566				continue567			}568			got := strconv.FormatFloat(f64, test.format, test.digits, 64)569			if got != test.want {570				t.Errorf("%v: got %s; want %s", test, got, test.want)571			}572		}573	}574}575 576func TestFloatFormat(t *testing.T) {577	for _, test := range []struct {578		format string579		value  any // float32, float64, or string (== 512bit *Float)580		want   string581	}{582		// from fmt/fmt_test.go583		{"%+.3e", 0.0, "+0.000e+00"},584		{"%+.3e", 1.0, "+1.000e+00"},585		{"%+.3f", -1.0, "-1.000"},586		{"%+.3F", -1.0, "-1.000"},587		{"%+.3F", float32(-1.0), "-1.000"},588		{"%+07.2f", 1.0, "+001.00"},589		{"%+07.2f", -1.0, "-001.00"},590		{"%+10.2f", +1.0, "     +1.00"},591		{"%+10.2f", -1.0, "     -1.00"},592		{"% .3E", -1.0, "-1.000E+00"},593		{"% .3e", 1.0, " 1.000e+00"},594		{"%+.3g", 0.0, "+0"},595		{"%+.3g", 1.0, "+1"},596		{"%+.3g", -1.0, "-1"},597		{"% .3g", -1.0, "-1"},598		{"% .3g", 1.0, " 1"},599		{"%b", float32(1.0), "8388608p-23"},600		{"%b", 1.0, "4503599627370496p-52"},601 602		// from fmt/fmt_test.go: old test/fmt_test.go603		{"%e", 1.0, "1.000000e+00"},604		{"%e", 1234.5678e3, "1.234568e+06"},605		{"%e", 1234.5678e-8, "1.234568e-05"},606		{"%e", -7.0, "-7.000000e+00"},607		{"%e", -1e-9, "-1.000000e-09"},608		{"%f", 1234.5678e3, "1234567.800000"},609		{"%f", 1234.5678e-8, "0.000012"},610		{"%f", -7.0, "-7.000000"},611		{"%f", -1e-9, "-0.000000"},612		{"%g", 1234.5678e3, "1.2345678e+06"},613		{"%g", float32(1234.5678e3), "1.2345678e+06"},614		{"%g", 1234.5678e-8, "1.2345678e-05"},615		{"%g", -7.0, "-7"},616		{"%g", -1e-9, "-1e-09"},617		{"%g", float32(-1e-9), "-1e-09"},618		{"%E", 1.0, "1.000000E+00"},619		{"%E", 1234.5678e3, "1.234568E+06"},620		{"%E", 1234.5678e-8, "1.234568E-05"},621		{"%E", -7.0, "-7.000000E+00"},622		{"%E", -1e-9, "-1.000000E-09"},623		{"%G", 1234.5678e3, "1.2345678E+06"},624		{"%G", float32(1234.5678e3), "1.2345678E+06"},625		{"%G", 1234.5678e-8, "1.2345678E-05"},626		{"%G", -7.0, "-7"},627		{"%G", -1e-9, "-1E-09"},628		{"%G", float32(-1e-9), "-1E-09"},629 630		{"%20.6e", 1.2345e3, "        1.234500e+03"},631		{"%20.6e", 1.2345e-3, "        1.234500e-03"},632		{"%20e", 1.2345e3, "        1.234500e+03"},633		{"%20e", 1.2345e-3, "        1.234500e-03"},634		{"%20.8e", 1.2345e3, "      1.23450000e+03"},635		{"%20f", 1.23456789e3, "         1234.567890"},636		{"%20f", 1.23456789e-3, "            0.001235"},637		{"%20f", 12345678901.23456789, "  12345678901.234568"},638		{"%-20f", 1.23456789e3, "1234.567890         "},639		{"%20.8f", 1.23456789e3, "       1234.56789000"},640		{"%20.8f", 1.23456789e-3, "          0.00123457"},641		{"%g", 1.23456789e3, "1234.56789"},642		{"%g", 1.23456789e-3, "0.00123456789"},643		{"%g", 1.23456789e20, "1.23456789e+20"},644		{"%20e", math.Inf(1), "                +Inf"},645		{"%-20f", math.Inf(-1), "-Inf                "},646 647		// from fmt/fmt_test.go: comparison of padding rules with C printf648		{"%.2f", 1.0, "1.00"},649		{"%.2f", -1.0, "-1.00"},650		{"% .2f", 1.0, " 1.00"},651		{"% .2f", -1.0, "-1.00"},652		{"%+.2f", 1.0, "+1.00"},653		{"%+.2f", -1.0, "-1.00"},654		{"%7.2f", 1.0, "   1.00"},655		{"%7.2f", -1.0, "  -1.00"},656		{"% 7.2f", 1.0, "   1.00"},657		{"% 7.2f", -1.0, "  -1.00"},658		{"%+7.2f", 1.0, "  +1.00"},659		{"%+7.2f", -1.0, "  -1.00"},660		{"%07.2f", 1.0, "0001.00"},661		{"%07.2f", -1.0, "-001.00"},662		{"% 07.2f", 1.0, " 001.00"},663		{"% 07.2f", -1.0, "-001.00"},664		{"%+07.2f", 1.0, "+001.00"},665		{"%+07.2f", -1.0, "-001.00"},666 667		// from fmt/fmt_test.go: zero padding does not apply to infinities668		{"%020f", math.Inf(-1), "                -Inf"},669		{"%020f", math.Inf(+1), "                +Inf"},670		{"% 020f", math.Inf(-1), "                -Inf"},671		{"% 020f", math.Inf(+1), "                 Inf"},672		{"%+020f", math.Inf(-1), "                -Inf"},673		{"%+020f", math.Inf(+1), "                +Inf"},674		{"%20f", -1.0, "           -1.000000"},675 676		// handle %v like %g677		{"%v", 0.0, "0"},678		{"%v", -7.0, "-7"},679		{"%v", -1e-9, "-1e-09"},680		{"%v", float32(-1e-9), "-1e-09"},681		{"%010v", 0.0, "0000000000"},682 683		// *Float cases684		{"%.20f", "1e-20", "0.00000000000000000001"},685		{"%.20f", "-1e-20", "-0.00000000000000000001"},686		{"%30.20f", "-1e-20", "       -0.00000000000000000001"},687		{"%030.20f", "-1e-20", "-00000000.00000000000000000001"},688		{"%030.20f", "+1e-20", "000000000.00000000000000000001"},689		{"% 030.20f", "+1e-20", " 00000000.00000000000000000001"},690 691		// erroneous formats692		{"%s", 1.0, "%!s(*big.Float=1)"},693	} {694		value := new(Float)695		switch v := test.value.(type) {696		case float32:697			value.SetPrec(24).SetFloat64(float64(v))698		case float64:699			value.SetPrec(53).SetFloat64(v)700		case string:701			value.SetPrec(512).Parse(v, 0)702		default:703			t.Fatalf("unsupported test value: %v (%T)", v, v)704		}705 706		if got := fmt.Sprintf(test.format, value); got != test.want {707			t.Errorf("%v: got %q; want %q", test, got, test.want)708		}709	}710}711 712func BenchmarkParseFloatSmallExp(b *testing.B) {713	for i := 0; i < b.N; i++ {714		for _, s := range []string{715			"1e0",716			"1e-1",717			"1e-2",718			"1e-3",719			"1e-4",720			"1e-5",721			"1e-10",722			"1e-20",723			"1e-50",724			"1e1",725			"1e2",726			"1e3",727			"1e4",728			"1e5",729			"1e10",730			"1e20",731			"1e50",732		} {733			var x Float734			_, _, err := x.Parse(s, 0)735			if err != nil {736				b.Fatalf("%s: %v", s, err)737			}738		}739	}740}741 742func BenchmarkParseFloatLargeExp(b *testing.B) {743	for i := 0; i < b.N; i++ {744		for _, s := range []string{745			"1e0",746			"1e-10",747			"1e-20",748			"1e-30",749			"1e-40",750			"1e-50",751			"1e-100",752			"1e-500",753			"1e-1000",754			"1e-5000",755			"1e-10000",756			"1e10",757			"1e20",758			"1e30",759			"1e40",760			"1e50",761			"1e100",762			"1e500",763			"1e1000",764			"1e5000",765			"1e10000",766		} {767			var x Float768			_, _, err := x.Parse(s, 0)769			if err != nil {770				b.Fatalf("%s: %v", s, err)771			}772		}773	}774}775 776func TestFloatScan(t *testing.T) {777	var floatScanTests = []struct {778		input     string779		format    string780		output    string781		remaining int782		wantErr   bool783	}{784		0: {"10.0", "%f", "10", 0, false},785		1: {"23.98+2.0", "%v", "23.98", 4, false},786		2: {"-1+1", "%v", "-1", 2, false},787		3: {" 00000", "%v", "0", 0, false},788		4: {"-123456p-78", "%b", "-4.084816388e-19", 0, false},789		5: {"+123", "%b", "123", 0, false},790		6: {"-1.234e+56", "%e", "-1.234e+56", 0, false},791		7: {"-1.234E-56", "%E", "-1.234e-56", 0, false},792		8: {"-1.234e+567", "%g", "-1.234e+567", 0, false},793		9: {"+1234567891011.234", "%G", "1.234567891e+12", 0, false},794 795		// Scan doesn't handle ±Inf.796		10: {"Inf", "%v", "", 3, true},797		11: {"-Inf", "%v", "", 3, true},798		12: {"-Inf", "%v", "", 3, true},799	}800 801	var buf bytes.Buffer802	for i, test := range floatScanTests {803		x := new(Float)804		buf.Reset()805		buf.WriteString(test.input)806		_, err := fmt.Fscanf(&buf, test.format, x)807		if test.wantErr {808			if err == nil {809				t.Errorf("#%d want non-nil err", i)810			}811			continue812		}813 814		if err != nil {815			t.Errorf("#%d error: %s", i, err)816		}817 818		if x.String() != test.output {819			t.Errorf("#%d got %s; want %s", i, x.String(), test.output)820		}821		if buf.Len() != test.remaining {822			t.Errorf("#%d got %d bytes remaining; want %d", i, buf.Len(), test.remaining)823		}824	}825}826 
codekingpro/portable-devtools · Team Ai