Make great documentation goal 1.2, and plan the README's reorganisation and the nested-template gaps #33
@@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -177,3 +178,10 @@ func (p *calcParser) ident() (CalcNode, error) {
|
|||||||
}
|
}
|
||||||
return CalcVar{name, at}, nil
|
return CalcVar{name, at}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Underflows reports a number written as text that reads as f = 0 though a digit before its
|
||||||
|
// exponent is not 0, as 1e-400 does: no float64 holds the number written.
|
||||||
|
func Underflows(text string, f float64) bool {
|
||||||
|
mantissa, _, _ := strings.Cut(strings.ToLower(text), "e")
|
||||||
|
return f == 0 && strings.ContainsAny(mantissa, "123456789")
|
||||||
|
}
|
||||||
|
|||||||
@@ -218,9 +218,13 @@ func (t *Table[O]) sumWeights() error {
|
|||||||
t.weights, t.cum = make([]float64, t.Len()), make([]float64, t.Len())
|
t.weights, t.cum = make([]float64, t.Len()), make([]float64, t.Len())
|
||||||
total := 0.0
|
total := 0.0
|
||||||
for r := range t.cum {
|
for r := range t.cum {
|
||||||
w, err := strconv.ParseFloat(t.Cell(r, t.weightIndex), 64)
|
cell := t.Cell(r, t.weightIndex)
|
||||||
|
w, err := strconv.ParseFloat(cell, 64)
|
||||||
if err != nil || math.IsInf(w, 0) || math.IsNaN(w) || w < 0 {
|
if err != nil || math.IsInf(w, 0) || math.IsNaN(w) || w < 0 {
|
||||||
return fmt.Errorf("%s line %d: weight %q is not a number of 0 or more", t.file, r+2, t.Cell(r, t.weightIndex))
|
return fmt.Errorf("%s line %d: weight %q is not a number of 0 or more", t.file, r+2, cell)
|
||||||
|
}
|
||||||
|
if grammar.Underflows(cell, w) {
|
||||||
|
return fmt.Errorf("%s line %d: weight %s is too close to 0 to tell from it", t.file, r+2, cell)
|
||||||
}
|
}
|
||||||
total += w
|
total += w
|
||||||
t.weights[r], t.cum[r] = w, total
|
t.weights[r], t.cum[r] = w, total
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/larvit/fejkdata/internal/datafiles"
|
"github.com/larvit/fejkdata/internal/datafiles"
|
||||||
"github.com/larvit/fejkdata/internal/grammar"
|
"github.com/larvit/fejkdata/internal/grammar"
|
||||||
@@ -385,11 +384,9 @@ func weightOf(raw any) (float64, error) {
|
|||||||
return w, notTiny("weight", wv, w)
|
return w, notTiny("weight", wv, w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// notTiny refuses the number v of option name where it reads as 0 though a digit of it is not
|
// notTiny refuses the number v of option name where grammar.Underflows does.
|
||||||
// 0, as 1e-400 does: no float64 holds the number written.
|
|
||||||
func notTiny(name string, v any, f float64) error {
|
func notTiny(name string, v any, f float64) error {
|
||||||
mantissa, _, _ := strings.Cut(strings.ToLower(string(v.(json.Number))), "e")
|
if grammar.Underflows(string(v.(json.Number)), f) {
|
||||||
if f == 0 && strings.ContainsAny(mantissa, "123456789") {
|
|
||||||
return fmt.Errorf("%s %s is too close to 0 to tell from it", name, v)
|
return fmt.Errorf("%s %s is too close to 0 to tell from it", name, v)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
Reference in New Issue
Block a user