PHP와 Lua에서 `log` 함수의 부동 소수점 부정확성(Floating-point Inaccuracy)으로 인한 비단조성(Non-monotonicity) 문제가 제기됨
특정 조건에서 `log(x, a) < log(x, b)`가 성립해야 하지만, PHP와 Lua에서는 결과가 반대로 나오거나 같게 표시되는 현상 발생
libm 라이브러리 구현 방식과 특정 밑(base)에 대한 특수 처리(Special Casing)가 원인으로 지목됨
Python, Rust, C# 등에서는 동일한 조건에서 올바른 결과 또는 다른 부정확성 패턴을 보임
논의에서는 `log(x, a)` 계산 시 `ln(x) / ln(a)` 공식을 사용하는 과정에서 발생하는 이중 반올림(Double Rounding) 및 나눗셈 오차(Division Error)가 핵심 문제로 지적된다. 특히 `log(x, 10)`과 같이 특정 밑(base)에 대한 직접 구현(Direct Implementation)이 존재할 경우, `ln(x) / ln(a)` 방식과 다른 계산 경로를 타게 된다. 이로 인해 경계선에서의 불연속성(Discontinuity at the Boundary)이 발생하며, 이는 예상치 못한 비단조성(Non-monotonicity)을 야기한다고 설명한다.
PHP와 Lua는 `log` 함수에서 밑(base)이 10 또는 2일 때, `ln(x) / ln(a)` 대신 `log10(x)` 또는 `log2(x)`를 직접 호출하는 최적화 기법(Optimization Technique)을 사용한다. 이는 해당 함수들이 더 빠르고 정확할 수 있기 때문이지만, 두 계산 방식 간의 가 누적되어 특정 입력값에서 `log(x, a) < log(x, b)`와 같은 을 위배하는 결과를 초래한다고 지적한다. 이는 의 트레이드오프(Trade-off)로 볼 수 있다.
Python, Rust, C# 등은 동일한 조건에서 다른 양상의 부동 소수점 결과를 보여준다. Python의 경우 `math.log`가 '같음(==)'으로 처리되는 반면, PHP와 Lua는 '작음(<)'으로 결과가 뒤집힌다. 이는 각 언어가 사용하는 수학 라이브러리(Math Library) 및 부동 소수점 처리 방식(Floating-point Handling)의 차이에서 기인한다. 커뮤니티에서는 이를 버그(Bug)라기보다는 간과된 이슈(Overlooked Issue)로 보며, `libm`의 `log10` 함수를 직접 추가하는 등 올바른 구현 방식(Correct Implementation)에 대한 논의가 이루어지고 있다.
PHP의 `log` 함수 시그니처는 기본값이 `M_E` (e의 근사값)를 나타내지만, 문서상으로는 기본값이 자연 로그(Natural Logarithm)라고 명시되어 있다. 이 모호한 정의(Ambiguous Definition)는 `log(x)`가 `log_M_E(x)`인지 `log_e(x)`인지 혼란을 야기하며, 실제로는 후자이지만 `ln(x) / ln(a)` 공식의 부정확성 때문에 두 결과가 일치하는 경우가 많다고 언급된다. Lua는 이 부분에 대해 좀 더 명확한 문서화를 제공하는 것으로 보인다.