This question already has answers here:
C and Python - different behaviour of the modulo (%) operation [duplicate]
(6 answers)
How does the modulo (%) operator work on negative numbers in Python?
(12 answers)
Closed 3 years ago.
this answer explains the modulo operation for positive numbers perfectly. But how does modulo operation work differently for negative integers? for example -1 % 60 == 59 in Python but -1 % 60 == -1 in C.
The C answer makes sense to me in that the logic is same as that for a modulo operation involving positive integers. But what's the skinny with the Python answer?
What is the general principle behind modulo operation for negative integers?
this answer doesn't explain the general principle.
TIA.
Related
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 4 months ago.
I'm observing some unexpected floating point behaviour in Elixir.
4.7 / 0.1 = 47.0 (good!)
4.8 / 0.1 = 47.9999999999 (bad!)
4.9 / 0.1 = 49 (good!)
While I understand the limitations of fp accuracy, in this case, the answer just looks wrong.
Curiously, I tried this in python as well, and got the same result, which is even more mysterious. When I changed the format to 4.8 * (1/0.1), I get the right answer (48.0).
What is going on here?
This is actually a normal behavior for IEEE 754 floating point numbers, and unrelated to erlang/elixir. Python or Nodejs would return the same thing.
For more information, you can read this detailed explanation.
While I understand the limitations of fp accuracy
Clearly not :-)
As always, if you need decimal precision, use Decimal:
iex(2)> Decimal.div(Decimal.new("4.8"), Decimal.new("0.1"))
#Decimal<48>
iex(3)> Decimal.mult(Decimal.new("4.8"), Decimal.new("10"))
#Decimal<48.0>
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 1 year ago.
I found this very simple calculation results incorrect: 0.19999999999999998.
(This is happened on Dartpad too)
void main() {
print(-0.1 + 0.3);
}
Why this is happened, and how to avoid ?
That's because you are loosing precision when using the type double.
To avoid that you have a few alternatives:
Use some decimal library like https://pub.dev/packages/decimal
Multiply by the number of significant digits and do the math using integers, some more information on a related SO question Dart double division precision
This is due to the internal representation of floating point numbers that crops up in almost all programming languages; c.f. this tutorial on floating point representation.
What's going on under the hood is that the string "-0.1" is converted into a string of bits that correspond to a particular number that is approximately equal to the value $-0.1$; same for $0.3$. When you subtract them, these approximation errors line up in such a way as to produce a result that you get by doing the math symbolically.
If you really need "exact" math on numbers like this, you can look into packages that provide either a Decimal or a Rational type.
This question already has answers here:
What's the difference between logical SSE intrinsics?
(3 answers)
What is the point of SSE2 instructions such as orpd?
(1 answer)
Which is the reason for avx floating point bitwise logical operations?
(3 answers)
Closed 1 year ago.
SSE has _mm_xor_ps, _mm_xor_pd, _mm_and_ps, _mm_and_pd, _mm_or_ps, _mm_or_pd.
As floating-point type consist of mantissa, exponent, and sign, the result of treating them as sequence of bits does not look meaningful (except xoring with self to have zero, but for this we have _mm_setzero_ps()/pd/si128).
If the purpose is still working as sequence of bits, then ps/pd distinction is not relevant, and integer versions look more appropriate: _mm_and_si128, _mm_xor_si128, _mm_or_si128
So what's the use case for these operations?
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 2 years ago.
j=1
for i=1,10 do
j=j-0.1
print(j)
end
the output is:
0.9
0.8
0.7
0.6
0.5
0.4
0.3
0.2
0.1
1.3877787807814e-16
where the last entry should be 0
Note: 0.1-0.1 returns 0.0
but, repeatedly doing j=j-0.1 from j>=0.3 produces this result
Numbers in lua are doubles which is Double-precision floating-point format, floating-point numbers has floating precision error. In fact 0.1 is not exactly 0.1, it's the closest representation of 0.1.
Possible fix would be probably using integers or integer with separate decimal part.
Related question with answer: C++ How to avoid floating-point arithmetic error
round off error!
0.1 cannot be represented exactly in IEEE 64 bit floating point
1/10 has a recurring representation in binary!
From what I understand, in mathematics, the mod operator is the result of the remainder of Euclidean division. Where 0 ≤ r < |b|, meaning that the result will always be positive.
In programming however, there are operators in many languages which can be used to mean either the remainder operator or modulo operator which differ with respect to how they handle negative values.
(I believe that mod operator in math, remainder operator in programming, and mod operator in programming yield the same results for positive numbers)
According to Modulo operation with negative numbers
"With a remainder operator, the sign of the result is the same as the
sign of the dividend while with a modulo operator the sign of the
result is the same as the divisor."
So the mod operator in programming is not referring to the mod operator in math?
Is the sign of the answer the main distinguishing factor between mod operator vs remainder operator in programming?
Mathematically, the modulus is part of group theory, and the idea of a set. You can generate all the numbers in a set by addition, with the modulus. So if your set is integers modulus 10, you count 0-9 and then start over at 0. There is no concept of a negative number under modulus.
In programming, the remainder is what portion is left after doing a division. So if you divide 3 by 10, you're left with 0 and a remainder of 3. If you divide -3 by 10, you get 0 with a remainder of -3, rather than -1 remainder 7. But the mathematical modulus is 7.
Those who designed integer division that we now use decided that it's more logical to round towards 0, rather than round towards negative infinity, so by necessity, a negative division will result in a negative remainder.
If you want to convert a remainder to a modulus, you need to add your modulus to any negative remainders in order to map them into the proper range.