Refactor civilization flow reward calculations for improved accuracy and performance
This commit is contained in:
@@ -303,6 +303,27 @@ static func split_arrays(remainders: Dictionary, key: String, count: Variant, id
|
||||
|
||||
|
||||
static func accumulate_rate(remainders: Dictionary, key: String, count: Variant, probability: Variant) -> Variant:
|
||||
# Reward rates are floats while populations are exact whole values. Keep
|
||||
# the product as quotient plus fractional carry instead of constructing an
|
||||
# intermediate Exact Value and flooring it again.
|
||||
if probability is float and is_finite(probability) and probability >= 0.0 and (count is int or (count is E.Value and count.fraction == 0.0)) and E.ge(count, 0):
|
||||
var terms: Array = E.parts(probability)
|
||||
if terms[2] > 0:
|
||||
var population: Array = E._blocks(count)[0]
|
||||
var whole_product: Array = E.Big.multiply(population, terms[0])
|
||||
var qr: Array = E.Big.divmod(whole_product, terms[1])
|
||||
var fractional: float = E._fraction_ratio(qr[1], terms[1])
|
||||
var carry: float = E.approx(remainders.get(key, 0))
|
||||
if carry >= 0.0 and carry < 1.0:
|
||||
if qr[1] == [0]:
|
||||
remainders[key] = carry
|
||||
return E._compose(qr[0])
|
||||
fractional += carry
|
||||
if fractional > 0.5 and absf(fractional - roundf(fractional)) <= 1e-12:
|
||||
fractional = roundf(fractional)
|
||||
var extra: int = floori(fractional)
|
||||
remainders[key] = fractional - extra
|
||||
return E.add(E._compose(qr[0]), extra)
|
||||
var product: Variant = E.multiply(count, E.maximum(0, probability))
|
||||
var carry: float = E.approx(remainders.get(key, 0))
|
||||
if carry >= 0.0 and carry < 1.0 and E.ge(product, 0):
|
||||
|
||||
Reference in New Issue
Block a user