Unclear Definition of Modulo / Remainder Operator in Expressions
Describe the bug
OpenSCEARIO defines the %
operator as follows:
For the definition of the arithmetic operators [IEEE 754] shall be used. It is noteworthy that % is the remainder operator, not the modulo operator. For integers greater than zero, both operators give equal results.
The first two sentences suggest that the IEEE remainder is intended to be used. The last sentence however contradicts this interpretation.
In programming languages, the %
operator is typically implemented in one of two ways, which I will refer to as Python %
and C %
, both of which differ from IEEE.
Input | Python % | C % | IEEE |
---|---|---|---|
7 % 3 | 1 | 1 | 1 |
3 % 5 | 3 | 3 | -2 |
-7 % 3 | 2 | -1 | -1 |
-3 % 5 | 2 | -3 | 2 |
The sentence
For integers greater than zero, both operators give equal results.
is only true when comparing Python %
and C %
, not IEEE
.
Considering that the C and C++ standards refer to %
as remainder, this leads me to belief that this is the intended implementation.
Furthermore, i would argue that of the three, the IEEE remainder is the implementation that produces the most unexpected results (3 % 5 == -2
) for users with programming background.
It should be noted that %
in C/C++ is only defined for integer types. The extension to floating-point types is implemented in fmod
.
Describe the expected behavior
The user guide should be amended to clearly define the %
operator, referring to a reference implementation, such as the Python %
-operator or fmod
. Examples should be added to the user guide similar to the table above, indluding integers and floating-point inputs.
Additional context
1
IEEE 754IEEE 754-2019 does not specify a modulo
operation. It specifies the remainder
operation as follows:
When
y ≠ 0
, the remainderr=remainder(x, y)
is defined for finite x and y [...] by the mathematical relationr = x - y * n
, where n is the integer nearest the exact numberx / y
; whenever|n - x/y| = ½
, then n is even.
This behavior is implemented e.g. by math.remainder
in Python and std::remainder
in C++.
2
PythonThe
%
(modulo) operator yields the remainder from the division of the first argument by the second. The numeric arguments are first converted to a common type. [...]. The arguments may be floating-point numbers, e.g.,3.14%0.7
equals 0.34 (since 3.14 equals4*0.7 + 0.34.
) The modulo operator always yields a result with the same sign as its second operand (or zero); the absolute value of the result is strictly smaller than the absolute value of the second operand.
The floor division and modulo operators are connected by the following identity:
x == (x//y)*y + (x%y)
.
3
CThe result of the / operator is the quotient from the division of the first operand by the second; the result of the % operator is the remainder. In both operations, if the value of the second operand is zero, the behavior is undefined.
When integers are divided, the result of the / operator is the algebraic quotient with any fractional part discarded. If the quotient
a/b
is representable, the expression(a/b)*b + a%b
shall equal a.
4
POSIX fmod[fmod] shall return the value x- i* y, for some integer i such that, if y is non-zero, the result has the same sign as x and magnitude less than the magnitude of y.
This behavior is implemented in C/C++ by fmod
and std::fmod
. For integers, it is identical to C %