func assertProb(t *T, b *Bayesian, expected *big.Rat, word string) { actual := b.ProbAWhenB(word) if expected.Cmp(actual) != 0 { t.Errorf("'%s' should be correlated %v:%v with Grinnell tweets, but was %v:%v\n", word, expected.Num(), expected.Denom(), actual.Num(), actual.Denom()) } }
// a.convertTo(t) converts the value of the analyzed expression a, // which must be a constant, ideal number, to a new analyzed // expression with a constant value of type t. // // TODO(austin) Rename to resolveIdeal or something? func (a *expr) convertTo(t Type) *expr { if !a.t.isIdeal() { log.Panicf("attempted to convert from %v, expected ideal", a.t) } var rat *big.Rat // XXX(Spec) The spec says "It is erroneous". // // It is an error to assign a value with a non-zero fractional // part to an integer, or if the assignment would overflow or // underflow, or in general if the value cannot be represented // by the type of the variable. switch a.t { case IdealFloatType: rat = a.asIdealFloat()() if t.isInteger() && !rat.IsInt() { a.diag("constant %v truncated to integer", rat.FloatString(6)) return nil } case IdealIntType: i := a.asIdealInt()() rat = new(big.Rat).SetInt(i) default: log.Panicf("unexpected ideal type %v", a.t) } // Check bounds if t, ok := t.lit().(BoundedType); ok { if rat.Cmp(t.minVal()) < 0 { a.diag("constant %v underflows %v", rat.FloatString(6), t) return nil } if rat.Cmp(t.maxVal()) > 0 { a.diag("constant %v overflows %v", rat.FloatString(6), t) return nil } } // Convert rat to type t. res := a.newExpr(t, a.desc) switch t := t.lit().(type) { case *uintType: n, d := rat.Num(), rat.Denom() f := new(big.Int).Quo(n, d) f = f.Abs(f) v := uint64(f.Int64()) res.eval = func(*Thread) uint64 { return v } case *intType: n, d := rat.Num(), rat.Denom() f := new(big.Int).Quo(n, d) v := f.Int64() res.eval = func(*Thread) int64 { return v } case *idealIntType: n, d := rat.Num(), rat.Denom() f := new(big.Int).Quo(n, d) res.eval = func() *big.Int { return f } case *floatType: n, d := rat.Num(), rat.Denom() v := float64(n.Int64()) / float64(d.Int64()) res.eval = func(*Thread) float64 { return v } case *idealFloatType: res.eval = func() *big.Rat { return rat } default: log.Panicf("cannot convert to type %T", t) } return res }
func binaryFloatOp(x *big.Rat, op token.Token, y *big.Rat) interface{} { var z big.Rat switch op { case token.ADD: return z.Add(x, y) case token.SUB: return z.Sub(x, y) case token.MUL: return z.Mul(x, y) case token.QUO: return z.Quo(x, y) case token.EQL: return x.Cmp(y) == 0 case token.NEQ: return x.Cmp(y) != 0 case token.LSS: return x.Cmp(y) < 0 case token.LEQ: return x.Cmp(y) <= 0 case token.GTR: return x.Cmp(y) > 0 case token.GEQ: return x.Cmp(y) >= 0 } panic("unreachable") }