...

Source file src/math/big/ratconv_test.go

Documentation: math/big

		 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  	"bytes"
		 9  	"fmt"
		10  	"io"
		11  	"math"
		12  	"strconv"
		13  	"strings"
		14  	"testing"
		15  )
		16  
		17  var exponentTests = []struct {
		18  	s			 string // string to be scanned
		19  	base2ok bool	 // true if 'p'/'P' exponents are accepted
		20  	sepOk	 bool	 // true if '_' separators are accepted
		21  	x			 int64	// expected exponent
		22  	b			 int		// expected exponent base
		23  	err		 error	// expected error
		24  	next		rune	 // next character (or 0, if at EOF)
		25  }{
		26  	// valid, without separators
		27  	{"", false, false, 0, 10, nil, 0},
		28  	{"1", false, false, 0, 10, nil, '1'},
		29  	{"e0", false, false, 0, 10, nil, 0},
		30  	{"E1", false, false, 1, 10, nil, 0},
		31  	{"e+10", false, false, 10, 10, nil, 0},
		32  	{"e-10", false, false, -10, 10, nil, 0},
		33  	{"e123456789a", false, false, 123456789, 10, nil, 'a'},
		34  	{"p", false, false, 0, 10, nil, 'p'},
		35  	{"P+100", false, false, 0, 10, nil, 'P'},
		36  	{"p0", true, false, 0, 2, nil, 0},
		37  	{"P-123", true, false, -123, 2, nil, 0},
		38  	{"p+0a", true, false, 0, 2, nil, 'a'},
		39  	{"p+123__", true, false, 123, 2, nil, '_'}, // '_' is not part of the number anymore
		40  
		41  	// valid, with separators
		42  	{"e+1_0", false, true, 10, 10, nil, 0},
		43  	{"e-1_0", false, true, -10, 10, nil, 0},
		44  	{"e123_456_789a", false, true, 123456789, 10, nil, 'a'},
		45  	{"P+1_00", false, true, 0, 10, nil, 'P'},
		46  	{"p-1_2_3", true, true, -123, 2, nil, 0},
		47  
		48  	// invalid: no digits
		49  	{"e", false, false, 0, 10, errNoDigits, 0},
		50  	{"ef", false, false, 0, 10, errNoDigits, 'f'},
		51  	{"e+", false, false, 0, 10, errNoDigits, 0},
		52  	{"E-x", false, false, 0, 10, errNoDigits, 'x'},
		53  	{"p", true, false, 0, 2, errNoDigits, 0},
		54  	{"P-", true, false, 0, 2, errNoDigits, 0},
		55  	{"p+e", true, false, 0, 2, errNoDigits, 'e'},
		56  	{"e+_x", false, true, 0, 10, errNoDigits, 'x'},
		57  
		58  	// invalid: incorrect use of separator
		59  	{"e0_", false, true, 0, 10, errInvalSep, 0},
		60  	{"e_0", false, true, 0, 10, errInvalSep, 0},
		61  	{"e-1_2__3", false, true, -123, 10, errInvalSep, 0},
		62  }
		63  
		64  func TestScanExponent(t *testing.T) {
		65  	for _, a := range exponentTests {
		66  		r := strings.NewReader(a.s)
		67  		x, b, err := scanExponent(r, a.base2ok, a.sepOk)
		68  		if err != a.err {
		69  			t.Errorf("scanExponent%+v\n\tgot error = %v; want %v", a, err, a.err)
		70  		}
		71  		if x != a.x {
		72  			t.Errorf("scanExponent%+v\n\tgot z = %v; want %v", a, x, a.x)
		73  		}
		74  		if b != a.b {
		75  			t.Errorf("scanExponent%+v\n\tgot b = %d; want %d", a, b, a.b)
		76  		}
		77  		next, _, err := r.ReadRune()
		78  		if err == io.EOF {
		79  			next = 0
		80  			err = nil
		81  		}
		82  		if err == nil && next != a.next {
		83  			t.Errorf("scanExponent%+v\n\tgot next = %q; want %q", a, next, a.next)
		84  		}
		85  	}
		86  }
		87  
		88  type StringTest struct {
		89  	in, out string
		90  	ok			bool
		91  }
		92  
		93  var setStringTests = []StringTest{
		94  	// invalid
		95  	{in: "1e"},
		96  	{in: "1.e"},
		97  	{in: "1e+14e-5"},
		98  	{in: "1e4.5"},
		99  	{in: "r"},
	 100  	{in: "a/b"},
	 101  	{in: "a.b"},
	 102  	{in: "1/0"},
	 103  	{in: "4/3/2"}, // issue 17001
	 104  	{in: "4/3/"},
	 105  	{in: "4/3."},
	 106  	{in: "4/"},
	 107  	{in: "13e-9223372036854775808"}, // CVE-2022-23772
	 108  
	 109  	// valid
	 110  	{"0", "0", true},
	 111  	{"-0", "0", true},
	 112  	{"1", "1", true},
	 113  	{"-1", "-1", true},
	 114  	{"1.", "1", true},
	 115  	{"1e0", "1", true},
	 116  	{"1.e1", "10", true},
	 117  	{"-0.1", "-1/10", true},
	 118  	{"-.1", "-1/10", true},
	 119  	{"2/4", "1/2", true},
	 120  	{".25", "1/4", true},
	 121  	{"-1/5", "-1/5", true},
	 122  	{"8129567.7690E14", "812956776900000000000", true},
	 123  	{"78189e+4", "781890000", true},
	 124  	{"553019.8935e+8", "55301989350000", true},
	 125  	{"98765432109876543210987654321e-10", "98765432109876543210987654321/10000000000", true},
	 126  	{"9877861857500000E-7", "3951144743/4", true},
	 127  	{"2169378.417e-3", "2169378417/1000000", true},
	 128  	{"884243222337379604041632732738665534", "884243222337379604041632732738665534", true},
	 129  	{"53/70893980658822810696", "53/70893980658822810696", true},
	 130  	{"106/141787961317645621392", "53/70893980658822810696", true},
	 131  	{"204211327800791583.81095", "4084226556015831676219/20000", true},
	 132  	{"0e9999999999", "0", true}, // issue #16176
	 133  }
	 134  
	 135  // These are not supported by fmt.Fscanf.
	 136  var setStringTests2 = []StringTest{
	 137  	// invalid
	 138  	{in: "4/3x"},
	 139  	{in: "0/-1"},
	 140  	{in: "-1/-1"},
	 141  
	 142  	// invalid with separators
	 143  	// (smoke tests only - a comprehensive set of tests is in natconv_test.go)
	 144  	{in: "10_/1"},
	 145  	{in: "_10/1"},
	 146  	{in: "1/1__0"},
	 147  
	 148  	// valid
	 149  	{"0b1000/3", "8/3", true},
	 150  	{"0B1000/0x8", "1", true},
	 151  	{"-010/1", "-8", true}, // 0-prefix indicates octal in this case
	 152  	{"-010.0", "-10", true},
	 153  	{"-0o10/1", "-8", true},
	 154  	{"0x10/1", "16", true},
	 155  	{"0x10/0x20", "1/2", true},
	 156  
	 157  	{"0010", "10", true}, // 0-prefix is ignored in this case (not a fraction)
	 158  	{"0x10.0", "16", true},
	 159  	{"0x1.8", "3/2", true},
	 160  	{"0X1.8p4", "24", true},
	 161  	{"0x1.1E2", "2289/2048", true}, // E is part of hex mantissa, not exponent
	 162  	{"0b1.1E2", "150", true},
	 163  	{"0B1.1P3", "12", true},
	 164  	{"0o10e-2", "2/25", true},
	 165  	{"0O10p-3", "1", true},
	 166  
	 167  	// valid with separators
	 168  	// (smoke tests only - a comprehensive set of tests is in natconv_test.go)
	 169  	{"0b_1000/3", "8/3", true},
	 170  	{"0B_10_00/0x8", "1", true},
	 171  	{"0xdead/0B1101_1110_1010_1101", "1", true},
	 172  	{"0B1101_1110_1010_1101/0XD_E_A_D", "1", true},
	 173  	{"1_000.0", "1000", true},
	 174  
	 175  	{"0x_10.0", "16", true},
	 176  	{"0x1_0.0", "16", true},
	 177  	{"0x1.8_0", "3/2", true},
	 178  	{"0X1.8p0_4", "24", true},
	 179  	{"0b1.1_0E2", "150", true},
	 180  	{"0o1_0e-2", "2/25", true},
	 181  	{"0O_10p-3", "1", true},
	 182  }
	 183  
	 184  func TestRatSetString(t *testing.T) {
	 185  	var tests []StringTest
	 186  	tests = append(tests, setStringTests...)
	 187  	tests = append(tests, setStringTests2...)
	 188  
	 189  	for i, test := range tests {
	 190  		x, ok := new(Rat).SetString(test.in)
	 191  
	 192  		if ok {
	 193  			if !test.ok {
	 194  				t.Errorf("#%d SetString(%q) expected failure", i, test.in)
	 195  			} else if x.RatString() != test.out {
	 196  				t.Errorf("#%d SetString(%q) got %s want %s", i, test.in, x.RatString(), test.out)
	 197  			}
	 198  		} else {
	 199  			if test.ok {
	 200  				t.Errorf("#%d SetString(%q) expected success", i, test.in)
	 201  			} else if x != nil {
	 202  				t.Errorf("#%d SetString(%q) got %p want nil", i, test.in, x)
	 203  			}
	 204  		}
	 205  	}
	 206  }
	 207  
	 208  func TestRatScan(t *testing.T) {
	 209  	var buf bytes.Buffer
	 210  	for i, test := range setStringTests {
	 211  		x := new(Rat)
	 212  		buf.Reset()
	 213  		buf.WriteString(test.in)
	 214  
	 215  		_, err := fmt.Fscanf(&buf, "%v", x)
	 216  		if err == nil != test.ok {
	 217  			if test.ok {
	 218  				t.Errorf("#%d (%s) error: %s", i, test.in, err)
	 219  			} else {
	 220  				t.Errorf("#%d (%s) expected error", i, test.in)
	 221  			}
	 222  			continue
	 223  		}
	 224  		if err == nil && x.RatString() != test.out {
	 225  			t.Errorf("#%d got %s want %s", i, x.RatString(), test.out)
	 226  		}
	 227  	}
	 228  }
	 229  
	 230  var floatStringTests = []struct {
	 231  	in	 string
	 232  	prec int
	 233  	out	string
	 234  }{
	 235  	{"0", 0, "0"},
	 236  	{"0", 4, "0.0000"},
	 237  	{"1", 0, "1"},
	 238  	{"1", 2, "1.00"},
	 239  	{"-1", 0, "-1"},
	 240  	{"0.05", 1, "0.1"},
	 241  	{"-0.05", 1, "-0.1"},
	 242  	{".25", 2, "0.25"},
	 243  	{".25", 1, "0.3"},
	 244  	{".25", 3, "0.250"},
	 245  	{"-1/3", 3, "-0.333"},
	 246  	{"-2/3", 4, "-0.6667"},
	 247  	{"0.96", 1, "1.0"},
	 248  	{"0.999", 2, "1.00"},
	 249  	{"0.9", 0, "1"},
	 250  	{".25", -1, "0"},
	 251  	{".55", -1, "1"},
	 252  }
	 253  
	 254  func TestFloatString(t *testing.T) {
	 255  	for i, test := range floatStringTests {
	 256  		x, _ := new(Rat).SetString(test.in)
	 257  
	 258  		if x.FloatString(test.prec) != test.out {
	 259  			t.Errorf("#%d got %s want %s", i, x.FloatString(test.prec), test.out)
	 260  		}
	 261  	}
	 262  }
	 263  
	 264  // Test inputs to Rat.SetString. The prefix "long:" causes the test
	 265  // to be skipped except in -long mode.	(The threshold is about 500us.)
	 266  var float64inputs = []string{
	 267  	// Constants plundered from strconv/testfp.txt.
	 268  
	 269  	// Table 1: Stress Inputs for Conversion to 53-bit Binary, < 1/2 ULP
	 270  	"5e+125",
	 271  	"69e+267",
	 272  	"999e-026",
	 273  	"7861e-034",
	 274  	"75569e-254",
	 275  	"928609e-261",
	 276  	"9210917e+080",
	 277  	"84863171e+114",
	 278  	"653777767e+273",
	 279  	"5232604057e-298",
	 280  	"27235667517e-109",
	 281  	"653532977297e-123",
	 282  	"3142213164987e-294",
	 283  	"46202199371337e-072",
	 284  	"231010996856685e-073",
	 285  	"9324754620109615e+212",
	 286  	"78459735791271921e+049",
	 287  	"272104041512242479e+200",
	 288  	"6802601037806061975e+198",
	 289  	"20505426358836677347e-221",
	 290  	"836168422905420598437e-234",
	 291  	"4891559871276714924261e+222",
	 292  
	 293  	// Table 2: Stress Inputs for Conversion to 53-bit Binary, > 1/2 ULP
	 294  	"9e-265",
	 295  	"85e-037",
	 296  	"623e+100",
	 297  	"3571e+263",
	 298  	"81661e+153",
	 299  	"920657e-023",
	 300  	"4603285e-024",
	 301  	"87575437e-309",
	 302  	"245540327e+122",
	 303  	"6138508175e+120",
	 304  	"83356057653e+193",
	 305  	"619534293513e+124",
	 306  	"2335141086879e+218",
	 307  	"36167929443327e-159",
	 308  	"609610927149051e-255",
	 309  	"3743626360493413e-165",
	 310  	"94080055902682397e-242",
	 311  	"899810892172646163e+283",
	 312  	"7120190517612959703e+120",
	 313  	"25188282901709339043e-252",
	 314  	"308984926168550152811e-052",
	 315  	"6372891218502368041059e+064",
	 316  
	 317  	// Table 14: Stress Inputs for Conversion to 24-bit Binary, <1/2 ULP
	 318  	"5e-20",
	 319  	"67e+14",
	 320  	"985e+15",
	 321  	"7693e-42",
	 322  	"55895e-16",
	 323  	"996622e-44",
	 324  	"7038531e-32",
	 325  	"60419369e-46",
	 326  	"702990899e-20",
	 327  	"6930161142e-48",
	 328  	"25933168707e+13",
	 329  	"596428896559e+20",
	 330  
	 331  	// Table 15: Stress Inputs for Conversion to 24-bit Binary, >1/2 ULP
	 332  	"3e-23",
	 333  	"57e+18",
	 334  	"789e-35",
	 335  	"2539e-18",
	 336  	"76173e+28",
	 337  	"887745e-11",
	 338  	"5382571e-37",
	 339  	"82381273e-35",
	 340  	"750486563e-38",
	 341  	"3752432815e-39",
	 342  	"75224575729e-45",
	 343  	"459926601011e+15",
	 344  
	 345  	// Constants plundered from strconv/atof_test.go.
	 346  
	 347  	"0",
	 348  	"1",
	 349  	"+1",
	 350  	"1e23",
	 351  	"1E23",
	 352  	"100000000000000000000000",
	 353  	"1e-100",
	 354  	"123456700",
	 355  	"99999999999999974834176",
	 356  	"100000000000000000000001",
	 357  	"100000000000000008388608",
	 358  	"100000000000000016777215",
	 359  	"100000000000000016777216",
	 360  	"-1",
	 361  	"-0.1",
	 362  	"-0", // NB: exception made for this input
	 363  	"1e-20",
	 364  	"625e-3",
	 365  
	 366  	// largest float64
	 367  	"1.7976931348623157e308",
	 368  	"-1.7976931348623157e308",
	 369  	// next float64 - too large
	 370  	"1.7976931348623159e308",
	 371  	"-1.7976931348623159e308",
	 372  	// the border is ...158079
	 373  	// borderline - okay
	 374  	"1.7976931348623158e308",
	 375  	"-1.7976931348623158e308",
	 376  	// borderline - too large
	 377  	"1.797693134862315808e308",
	 378  	"-1.797693134862315808e308",
	 379  
	 380  	// a little too large
	 381  	"1e308",
	 382  	"2e308",
	 383  	"1e309",
	 384  
	 385  	// way too large
	 386  	"1e310",
	 387  	"-1e310",
	 388  	"1e400",
	 389  	"-1e400",
	 390  	"long:1e400000",
	 391  	"long:-1e400000",
	 392  
	 393  	// denormalized
	 394  	"1e-305",
	 395  	"1e-306",
	 396  	"1e-307",
	 397  	"1e-308",
	 398  	"1e-309",
	 399  	"1e-310",
	 400  	"1e-322",
	 401  	// smallest denormal
	 402  	"5e-324",
	 403  	"4e-324",
	 404  	"3e-324",
	 405  	// too small
	 406  	"2e-324",
	 407  	// way too small
	 408  	"1e-350",
	 409  	"long:1e-400000",
	 410  	// way too small, negative
	 411  	"-1e-350",
	 412  	"long:-1e-400000",
	 413  
	 414  	// try to overflow exponent
	 415  	// [Disabled: too slow and memory-hungry with rationals.]
	 416  	// "1e-4294967296",
	 417  	// "1e+4294967296",
	 418  	// "1e-18446744073709551616",
	 419  	// "1e+18446744073709551616",
	 420  
	 421  	// https://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
	 422  	"2.2250738585072012e-308",
	 423  	// https://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
	 424  	"2.2250738585072011e-308",
	 425  
	 426  	// A very large number (initially wrongly parsed by the fast algorithm).
	 427  	"4.630813248087435e+307",
	 428  
	 429  	// A different kind of very large number.
	 430  	"22.222222222222222",
	 431  	"long:2." + strings.Repeat("2", 4000) + "e+1",
	 432  
	 433  	// Exactly halfway between 1 and math.Nextafter(1, 2).
	 434  	// Round to even (down).
	 435  	"1.00000000000000011102230246251565404236316680908203125",
	 436  	// Slightly lower; still round down.
	 437  	"1.00000000000000011102230246251565404236316680908203124",
	 438  	// Slightly higher; round up.
	 439  	"1.00000000000000011102230246251565404236316680908203126",
	 440  	// Slightly higher, but you have to read all the way to the end.
	 441  	"long:1.00000000000000011102230246251565404236316680908203125" + strings.Repeat("0", 10000) + "1",
	 442  
	 443  	// Smallest denormal, 2^(-1022-52)
	 444  	"4.940656458412465441765687928682213723651e-324",
	 445  	// Half of smallest denormal, 2^(-1022-53)
	 446  	"2.470328229206232720882843964341106861825e-324",
	 447  	// A little more than the exact half of smallest denormal
	 448  	// 2^-1075 + 2^-1100.	(Rounds to 1p-1074.)
	 449  	"2.470328302827751011111470718709768633275e-324",
	 450  	// The exact halfway between smallest normal and largest denormal:
	 451  	// 2^-1022 - 2^-1075.	(Rounds to 2^-1022.)
	 452  	"2.225073858507201136057409796709131975935e-308",
	 453  
	 454  	"1152921504606846975",	//	 1<<60 - 1
	 455  	"-1152921504606846975", // -(1<<60 - 1)
	 456  	"1152921504606846977",	//	 1<<60 + 1
	 457  	"-1152921504606846977", // -(1<<60 + 1)
	 458  
	 459  	"1/3",
	 460  }
	 461  
	 462  // isFinite reports whether f represents a finite rational value.
	 463  // It is equivalent to !math.IsNan(f) && !math.IsInf(f, 0).
	 464  func isFinite(f float64) bool {
	 465  	return math.Abs(f) <= math.MaxFloat64
	 466  }
	 467  
	 468  func TestFloat32SpecialCases(t *testing.T) {
	 469  	for _, input := range float64inputs {
	 470  		if strings.HasPrefix(input, "long:") {
	 471  			if !*long {
	 472  				continue
	 473  			}
	 474  			input = input[len("long:"):]
	 475  		}
	 476  
	 477  		r, ok := new(Rat).SetString(input)
	 478  		if !ok {
	 479  			t.Errorf("Rat.SetString(%q) failed", input)
	 480  			continue
	 481  		}
	 482  		f, exact := r.Float32()
	 483  
	 484  		// 1. Check string -> Rat -> float32 conversions are
	 485  		// consistent with strconv.ParseFloat.
	 486  		// Skip this check if the input uses "a/b" rational syntax.
	 487  		if !strings.Contains(input, "/") {
	 488  			e64, _ := strconv.ParseFloat(input, 32)
	 489  			e := float32(e64)
	 490  
	 491  			// Careful: negative Rats too small for
	 492  			// float64 become -0, but Rat obviously cannot
	 493  			// preserve the sign from SetString("-0").
	 494  			switch {
	 495  			case math.Float32bits(e) == math.Float32bits(f):
	 496  				// Ok: bitwise equal.
	 497  			case f == 0 && r.Num().BitLen() == 0:
	 498  				// Ok: Rat(0) is equivalent to both +/- float64(0).
	 499  			default:
	 500  				t.Errorf("strconv.ParseFloat(%q) = %g (%b), want %g (%b); delta = %g", input, e, e, f, f, f-e)
	 501  			}
	 502  		}
	 503  
	 504  		if !isFinite(float64(f)) {
	 505  			continue
	 506  		}
	 507  
	 508  		// 2. Check f is best approximation to r.
	 509  		if !checkIsBestApprox32(t, f, r) {
	 510  			// Append context information.
	 511  			t.Errorf("(input was %q)", input)
	 512  		}
	 513  
	 514  		// 3. Check f->R->f roundtrip is non-lossy.
	 515  		checkNonLossyRoundtrip32(t, f)
	 516  
	 517  		// 4. Check exactness using slow algorithm.
	 518  		if wasExact := new(Rat).SetFloat64(float64(f)).Cmp(r) == 0; wasExact != exact {
	 519  			t.Errorf("Rat.SetString(%q).Float32().exact = %t, want %t", input, exact, wasExact)
	 520  		}
	 521  	}
	 522  }
	 523  
	 524  func TestFloat64SpecialCases(t *testing.T) {
	 525  	for _, input := range float64inputs {
	 526  		if strings.HasPrefix(input, "long:") {
	 527  			if !*long {
	 528  				continue
	 529  			}
	 530  			input = input[len("long:"):]
	 531  		}
	 532  
	 533  		r, ok := new(Rat).SetString(input)
	 534  		if !ok {
	 535  			t.Errorf("Rat.SetString(%q) failed", input)
	 536  			continue
	 537  		}
	 538  		f, exact := r.Float64()
	 539  
	 540  		// 1. Check string -> Rat -> float64 conversions are
	 541  		// consistent with strconv.ParseFloat.
	 542  		// Skip this check if the input uses "a/b" rational syntax.
	 543  		if !strings.Contains(input, "/") {
	 544  			e, _ := strconv.ParseFloat(input, 64)
	 545  
	 546  			// Careful: negative Rats too small for
	 547  			// float64 become -0, but Rat obviously cannot
	 548  			// preserve the sign from SetString("-0").
	 549  			switch {
	 550  			case math.Float64bits(e) == math.Float64bits(f):
	 551  				// Ok: bitwise equal.
	 552  			case f == 0 && r.Num().BitLen() == 0:
	 553  				// Ok: Rat(0) is equivalent to both +/- float64(0).
	 554  			default:
	 555  				t.Errorf("strconv.ParseFloat(%q) = %g (%b), want %g (%b); delta = %g", input, e, e, f, f, f-e)
	 556  			}
	 557  		}
	 558  
	 559  		if !isFinite(f) {
	 560  			continue
	 561  		}
	 562  
	 563  		// 2. Check f is best approximation to r.
	 564  		if !checkIsBestApprox64(t, f, r) {
	 565  			// Append context information.
	 566  			t.Errorf("(input was %q)", input)
	 567  		}
	 568  
	 569  		// 3. Check f->R->f roundtrip is non-lossy.
	 570  		checkNonLossyRoundtrip64(t, f)
	 571  
	 572  		// 4. Check exactness using slow algorithm.
	 573  		if wasExact := new(Rat).SetFloat64(f).Cmp(r) == 0; wasExact != exact {
	 574  			t.Errorf("Rat.SetString(%q).Float64().exact = %t, want %t", input, exact, wasExact)
	 575  		}
	 576  	}
	 577  }
	 578  
	 579  func TestIssue31184(t *testing.T) {
	 580  	var x Rat
	 581  	for _, want := range []string{
	 582  		"-213.090",
	 583  		"8.192",
	 584  		"16.000",
	 585  	} {
	 586  		x.SetString(want)
	 587  		got := x.FloatString(3)
	 588  		if got != want {
	 589  			t.Errorf("got %s, want %s", got, want)
	 590  		}
	 591  	}
	 592  }
	 593  
	 594  func TestIssue45910(t *testing.T) {
	 595  	var x Rat
	 596  	for _, test := range []struct {
	 597  		input string
	 598  		want	bool
	 599  	}{
	 600  		{"1e-1000001", false},
	 601  		{"1e-1000000", true},
	 602  		{"1e+1000000", true},
	 603  		{"1e+1000001", false},
	 604  
	 605  		{"0p1000000000000", true},
	 606  		{"1p-10000001", false},
	 607  		{"1p-10000000", true},
	 608  		{"1p+10000000", true},
	 609  		{"1p+10000001", false},
	 610  		{"1.770p02041010010011001001", false}, // test case from issue
	 611  	} {
	 612  		_, got := x.SetString(test.input)
	 613  		if got != test.want {
	 614  			t.Errorf("SetString(%s) got ok = %v; want %v", test.input, got, test.want)
	 615  		}
	 616  	}
	 617  }
	 618  

View as plain text