log is non-monotonous in PHP and LuaJuly 22, 2026If a>b>1 and x>1, you can prove that logax<logbx. (As a reminder, logax denotes the value t such that x=at.) This is very intuitive if you think about it: for “normal” numbers, the greater a, the smaller t you will need to get the same x.Yet if you ask PHP what it thinks, it will tell you you’re wrong in a couple rare cases:<?php $x = 2.93; $a = 10 + 2 ** -49; $b = 10; assert($a > $b); var_dump(log($x, $a) < log($x, $b)); var_dump(log($x, $a) == log($x, $b)); To be clear, this is not the usual floating-point inaccuracy. Everyone already knows floating-point operations are imprecise and it wouldn’t be fun to blog about. This example was deliberately engineered to trigger something different.It would be completely natural if the produced result indicated logax=logbx instead of <: not all real numbers can be exactly represented as floats, so rounding can cause close results to appear equal. In fact, on the same numbers, Python’s math.log produces the “equals” result. In PHP, however, the result somehow flips. And in Lua, too! But not in Rust or C#. All on the same machine and OS! How come?Also note that I’m only changing the base: if I also changed the argument, I would find lots of counterexamples that work in any language, e.g.:log(243 ** 3, 3 ** 3) != log(243, 3) …because the formula used for log is imperfect. That’s not what we’re discussing.Log baseTo find why this happens, let’s discuss how languages usually implement math.log.libm, the library that provides transcendental functions, exposes multiple functions for computing logarithms: log, log10, log2, etc. Each function handles a single base: log uses base e, log10 uses base 10, and so on. While there are no guarantees on their precision, they are usually pretty good, and at least monotonous (brute-force).But there is no function for an arbitrary base, so languages providing a two-argument log have to cheat. Mathematically, logax=lnxlna, so you can comp...
First seen: 2026-07-22 10:42
Last seen: 2026-07-23 16:06