From ff80847af6420e62b55ab739f1aac4c715683886 Mon Sep 17 00:00:00 2001 From: David Walker Date: Fri, 9 Aug 2024 16:26:01 -0700 Subject: [PATCH] MISC: Improve rep calculation accuracy (#1559) --- src/Faction/formulas/favor.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Faction/formulas/favor.ts b/src/Faction/formulas/favor.ts index e86bb7dc3..05af1fa24 100644 --- a/src/Faction/formulas/favor.ts +++ b/src/Faction/formulas/favor.ts @@ -5,13 +5,18 @@ import { clampNumber } from "../../utils/helpers/clampNumber"; export const MaxFavor = 35331; +// This is the nearest representable value of log(1.02), which is the base of our power. +// It is *not* the same as Math.log(1.02), since "1.02" lacks sufficient precision. +const log1point02 = 0.019802627296179712; export function favorToRep(f: number): number { - return clampNumber(25000 * (Math.pow(1.02, f) - 1), 0); + // expm1 is e^x - 1, which is more accurate for small x than doing it the obvious way. + return clampNumber(25000 * Math.expm1(log1point02 * f), 0); } export function repToFavor(r: number): number { - return clampNumber(Math.log(r / 25000 + 1) / Math.log(1.02), 0, MaxFavor); + // log1p is log(x + 1), which is more accurate for small x than doing it the obvious way. + return clampNumber(Math.log1p(r / 25000) / log1point02, 0, MaxFavor); } export function calculateFavorAfterResetting(favor: number, playerReputation: number) {