summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2019-12-29 13:01:54 -0500
committerLuke Shumaker <lukeshu@lukeshu.com>2019-12-29 13:01:54 -0500
commitc4f2a2f72ac43e319067756c7757a5a15ebb172e (patch)
tree0bf00c6ec0d0d3fbb6ad730b010515aa2367781f
parentf446f62eb968ba9479abcd1d2b00794340e78153 (diff)
preroll: Use fewer floating-point operations when calculating variance
-rw-r--r--preroll.go19
1 files changed, 11 insertions, 8 deletions
diff --git a/preroll.go b/preroll.go
index ae9d5a3..ab3d0a0 100644
--- a/preroll.go
+++ b/preroll.go
@@ -1,4 +1,4 @@
-/* Copyright (C) 2011, 2013-2014, 2017 Luke Shumaker <lukeshu@sbcglobal.net> */
+/* Copyright (C) 2011, 2013-2014, 2017, 2019 Luke Shumaker <lukeshu@sbcglobal.net> */
package main
import (
@@ -35,14 +35,17 @@ func rollSpec(spec string) (mean float64, variance float64) {
dice = 1
}
- // mean is E(X)
+ // - Let 'd' be the die_size
+ // - Let 'X' be the the uniform random variable that is the result of a 1d${d} roll
+ // - E(X) = (1+d)/2
mean = float64(1 + die_size)/2.0
-
- // sum is Σi² for i=1..die_size
- sum := (die_size*(die_size+1)*(2*die_size+1))/6
- // mean2 is E(X²)
- mean2 := float64(sum)/float64(die_size)
- variance = mean2-(mean*mean)
+ // - Var(X) = E(X²)-E(X)²
+ // - E(X²) = (Σi² for i=1..d) / d
+ // = ¹/₆d(d+1)(2d+1) / d
+ // = d(d+1)(2d+1) / (6d)
+ // ∴ Var(X) = (d(d+1)(2d+1) / (6d)) - ((1+d)/2)²
+ // = ¹/₁₂(d+1)(d-1)
+ variance = float64((die_size+1)*(die_size-1))/12.0
mean *= float64(dice)
variance *= float64(dice)