// currencyUnits converts a types.Currency to a string with human-readable // units. The unit used will be the largest unit that results in a value // greater than 1. The value is rounded to 4 significant digits. func currencyUnits(c types.Currency) string { pico := types.SiacoinPrecision.Div64(1e12) if c.Cmp(pico) < 0 { return c.String() + " H" } // iterate until we find a unit greater than c mag := pico unit := "" for _, unit = range []string{"pS", "nS", "uS", "mS", "SC", "KS", "MS", "GS", "TS"} { if c.Cmp(mag.Mul64(1e3)) < 0 { break } else if unit != "TS" { // don't want to perform this multiply on the last iter; that // would give us 1.235 TS instead of 1235 TS mag = mag.Mul64(1e3) } } num := new(big.Rat).SetInt(c.Big()) denom := new(big.Rat).SetInt(mag.Big()) res, _ := new(big.Rat).Mul(num, denom.Inv(denom)).Float64() return fmt.Sprintf("%.4g %s", res, unit) }
func (me *StatisticalAccumulator) Mean() *big.Rat { mean := new(big.Rat) mean.Inv(me.n) mean.Mul(mean, me.sigmaXI) return mean }
// ratScale multiplies x by 10**exp. func ratScale(x *big.Rat, exp int) { if exp < 0 { x.Inv(x) ratScale(x, -exp) x.Inv(x) return } for exp >= 9 { x.Quo(x, bigRatBillion) exp -= 9 } for exp >= 1 { x.Quo(x, bigRatTen) exp-- } }
// Returns an approximate Birthday probability calculation // based on the number of blocks given and the hash size. // // It uses the simplified calculation: p = k(k-1) / (2N) // // From http://preshing.com/20110504/hash-collision-probabilities/ func BirthdayProblem(blocks int) string { k := big.NewInt(int64(blocks)) km1 := big.NewInt(int64(blocks - 1)) ksq := k.Mul(k, km1) n := big.NewInt(0) n = n.Exp(big.NewInt(2), big.NewInt(int64(HashSize)*8), nil) twoN := n.Add(n, n) var t, t2 big.Rat var res *big.Rat // res = t.SetFrac(ksq, twoN) f64, _ := res.Float64() inv := t2.Inv(res).FloatString(0) invs := fmt.Sprintf(" ~ 1/%s ~ %v", inv, f64) return "Collision probability is" + invs }
func (me *StatisticalAccumulator) Variance() *big.Rat { variance := new(big.Rat) variance.Inv(me.n) variance.Mul(variance, me.sigmaXISquared) temp := new(big.Rat) temp.Mul(me.n, me.n) temp.Inv(temp) temp.Mul(temp, me.sigmaXI) temp.Mul(temp, me.sigmaXI) variance.Sub(variance, temp) return variance }
// ratExponent returns the power of ten that x would display in scientific notation. func ratExponent(x *big.Rat) int { if x.Sign() < 0 { x.Neg(x) } e := 0 invert := false if x.Num().Cmp(x.Denom()) < 0 { invert = true x.Inv(x) e++ } for x.Cmp(bigRatBillion) >= 0 { e += 9 x.Quo(x, bigRatBillion) } for x.Cmp(bigRatTen) > 0 { e++ x.Quo(x, bigRatTen) } if invert { return -e } return e }
// How many fractions contain a numerator with more digits than the denominator? func problem57() int { sum := 0 // Number of fractions meeting the description. const limit = 1000 // Given in problem description. one := new(big.Rat).SetInt64(1) two := new(big.Rat).SetInt64(2) // result will be re-used each iteration to store the // current value of the fractional expansion. result := new(big.Rat) // tail will be re-used each iteration to store the // current value of the repeating component of the expansion. // That component is 2, (2 + 1/2), (2 + 1/(2 + 1/2)), ... tail := new(big.Rat).SetInt64(2) for i := 0; i < limit; i++ { temp := new(big.Rat) tail.Add(two, temp.Inv(tail)) // tail = (2 + 1/tail) result.Add(one, temp.Inv(tail)) // result = (1 + 1/tail) if checkNumerator(result) { sum++ } } return sum }
// Mul multiplies the difficulty of a target by y. The product is defined by: // y / x func (x Target) MulDifficulty(y *big.Rat) (t Target) { product := new(big.Rat).Mul(y, x.Inverse()) product = product.Inv(product) return RatToTarget(product) }
// Wrapper for dividing two values func Div(x, y *big.Rat) *big.Rat { yinv := y.Inv(y) z := x.Mul(x, yinv) return z }