From 3d84fb64c3426fce69976fb93fb48d389a7390f3 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Sun, 7 Nov 2021 20:48:38 +0000 Subject: [PATCH] LibJS: Add a modulo() function to represent the "x modulo y" notation This *not* being the same as C++ "%" in all cases is a massive footgun, and hopefully one I came across for the last time. --- .../Libraries/LibJS/Runtime/AbstractOperations.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.h b/Userland/Libraries/LibJS/Runtime/AbstractOperations.h index a935932084..1f68721298 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.h +++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.h @@ -76,4 +76,18 @@ ThrowCompletionOr ordinary_create_from_constructor(GlobalObject& global_obje return global_object.heap().allocate(global_object, forward(args)..., *prototype); } +// x modulo y, https://tc39.es/ecma262/#eqn-modulo +template +T modulo(T x, T y) +{ + // The notation “x modulo y” (y must be finite and non-zero) computes a value k of the same sign as y (or zero) such that abs(k) < abs(y) and x - k = q × y for some integer q. + VERIFY(y != 0); + if constexpr (IsFloatingPoint) { + VERIFY(isfinite(y)); + return fmod(fmod(x, y) + y, y); + } else { + return ((x % y) + y) % y; + } +} + }