1package sheet23import (4 "fmt"5 "math"6 "math/rand/v2"7 "strconv"8 "strings"9 "testing"10)1112// printedDec is numDec found only by printing v, as for inputs13// plainDec leaves.14func printedDec(v float64, input string) (uint8, bool) {15 if strconv.FormatFloat(v, 'f', -1, 64) == input {16 return 0, true17 }18 i := strings.IndexByte(input, '.')19 if i < 0 || len(input)-i-1 >= maxDec {20 return 0, false21 }22 d := len(input) - i - 123 if strconv.FormatFloat(v, 'f', d, 64) == input {24 return uint8(d + 1), true25 }26 return 0, false27}2829// Where plainDec answers without printing, it answers as printing does.30func TestPlainDecAsPrinted(t *testing.T) {31 inputs := []string{"0", "-0", "0.0", "-0.0", "0.50", "1.5", "100", "100.0", "12.30", "007", "0.1", "0.000", "1e5", ".5", "5.",32 "123456789012345", "1234567890123456", "0.000000000000000000001", "99999999999999.9", "-42.4200", "1,200", "$5", "1.2.3", "--1", "+1"}33 r := rand.New(rand.NewPCG(3, 4))34 for range 20000 {35 switch r.IntN(3) {36 case 0:37 inputs = append(inputs, fmt.Sprintf("%.*f", r.IntN(8), (r.Float64()-0.5)*math.Pow(10, float64(r.IntN(18)))))38 case 1:39 inputs = append(inputs, strconv.FormatInt(r.Int64N(1e17)-5e16, 10))40 default:41 inputs = append(inputs, strconv.FormatFloat(r.NormFloat64()*1e6, 'f', -1, 64))42 }43 }44 answered := 045 for _, in := range inputs {46 v, err := strconv.ParseFloat(in, 64)47 if err != nil {48 continue49 }50 d, ok := plainDec(v, in)51 if !ok {52 continue53 }54 answered++55 if pd, pok := printedDec(v, in); !pok || pd != d {56 t.Errorf("%q: plainDec %d, printed %d %v", in, d, pd, pok)57 }58 }59 if answered < len(inputs)/5 {60 t.Errorf("plainDec answered %d of %d", answered, len(inputs))61 }62}