News for hackers. Stuff that matters.
Re:Aztec monks with 1/55 HP no longer die when picking up or... by zelphirkalt on Saturday April 15, 2023 @07:29AM (#35579639)
The difference is, that with rationals you do not lose any precision on the way. I doubt, that 99^k is part of AoE2 code. For the simple calculations in AoE2 regarding unit health, rationals will do a fine job. With rationals the rounding does not happen during the precise calculation. It happens explicitly, only once, at the end of the calculation, at the programmer's wish and conscious decision, thereby avoiding the kind of issue we see here.

Rationals might not be the solve all problems type, but here they seem very applicable.

Re:Aztec monks with 1/55 HP no longer die when picking up or... by perihelions on Saturday April 15, 2023 @09:27AM (#35580449)
It's a common pattern, in its more general forms. Sure, you can abstract away the naive re-implementation of exp()

    loop { x ← a*x } 
as one functional call x(t) = exp(-k*t), so that one looks pointless. But moving-average type expressions

    loop { x ← a*x + f(t) } 
are more interesting. You can't generally refactor those into exp() calls, like x(t) = sum[ f(t_i) * exp(-k*(t - t_i)) ], since that introduces a memory leak – you need to hold an explicit list of all the past values of f(t), in order to compute it this way. That's why the pattern [0] is uniquely useful: it's a trick to incrementally accumulate a moving average using just one variable of state.

[0] https://en.wikipedia.org/wiki/Moving_average#Exponential_mov...

Here's one uncontrived way this pattern might show up: "the NPC has a numeric disposition towards the player, and the player's actions have positive and negative effects on it. These effects have finite duration, and disposition decays back to the neutral value". Another way: you have a large list (like a time series) you want to reduce to a small one by interpolation. Another way: you have some PID-like controller in your program, and to make it behave, you need a cheap filter to clean a jittery input signal. (I'm building these for my Factorio factories right now – it's the only reason this example occurred to me. "x ← (99/100) * x" is a factory control component I had to implement out of int32_t's).

Re:Aztec monks with 1/55 HP no longer die when picking up or... by hinkley on Saturday April 15, 2023 @12:13PM (#35581971)
In a simulation nobody is calculating n x m^k. They’re calculating n X m in k loops spread over k ticks. And given that fact, if you round or truncate at the end of each cycle, as one often does with game points (eg, fire resistance in D&D), then there is no problem.

For money systems, we also tend to round on every step to the nearest penny.

What you don’t have with rationals is the problem of 10.00 - 4.10 + 3.20 ending in a 9.