Wed 22 Jul 2015 04:58:49 PM UTC, comment #12:
I changed Octave to follow Matlab conventions both for returning NaN and for the signbit of the output. See this cset (http://hg.savannah.gnu.org/hgweb/octave/rev/0cefba1a1030). Closing report.
|
Wed 22 Jul 2015 08:00:55 AM UTC, comment #11:
Rik,
Here are Matlab 2015a results
|
Wed 22 Jul 2015 03:31:08 AM UTC, comment #10:
Matlab, for whatever reason, rounds nearby floating point values to integers. Octave was forced to implement it because we get so many complaints when we are not exactly Matlab compatible.
I have some more tests to run.
|
Tue 21 Jul 2015 06:36:28 PM UTC, comment #9:
A key point about the C/C++ function fmod (and the related remainder
function) is that it is exact (even with floating-point numbers). In
lots of applications this is important.
It is unfortunate the Octave (and MATLAB) resort to cosmetic "fixes" to
ensure that
rem(0.94, 0.01)
returns 0.
Let's see how to do the rem operation exactly
a=0.94;
b=0.01;
a and b are now the closest floating point numbers to 0.94 and 0.01.
Now compute
((((a-64b)-16b)-8b)-4b)-b
Each of the multiplication and subtraction operations here is exact and
this yields
0.00999999999999993
and this is less that b
ans < b -> 1
|
Tue 21 Jul 2015 06:21:26 PM UTC, comment #8:
The Wikipedia page:
https://en.wikipedia.org/wiki/Modulo_operation
has a relevant, but long, story.
|
Tue 21 Jul 2015 06:09:24 PM UTC, comment #7:
I don't think MATLAB treats "second arg = 1" as a special case. For
example
atan2d(rem(-0,360),-1) -> -180
Here are the other cases you asked for...
atan2d(rem(-0, 0), -1) -> NaN
atan2d(rem(-0, -0), -1) -> NaN
atan2d(rem([-0 0], [0 0]), [-1 -1]) -> NaN NaN
atan2d(rem([-0 0], [1 1]), [-1 -1]) -> -180 180
atan2d(rem(4, -0), -1) -> NaN
atan2d(rem(-4, -0), -1) -> NaN
atan2d(rem(4, 1), -1) -> 180
atan2d(rem(-4, 1), -1) -> -180
I believe that this behavior mimics that of the C++ function std::fmod.
|
Tue 21 Jul 2015 06:07:06 PM UTC, comment #6:
And, your comment which just appears looks right.
See the NaNs...
|
Tue 21 Jul 2015 06:05:47 PM UTC, comment #5:
@Michael: If that is correct, I see another change necessary. Octave never returns NaN. I think it may often be a useful fiction in algorithms to pretend that rem (x,0) == 0 so that might be worth discussing on the maintainer's list.
|
Tue 21 Jul 2015 05:59:11 PM UTC, comment #4:
Using matlab 2015a produces the same results and
help rem says, in part:
REM(x,0) is NaN.
REM(x,x), for x~=0, is 0.
REM(x,y), for x~=y and y~=0, has the same sign as x.
So, they really intend to return -0 and that would
be the right choice for Octave even though Octave,
appropriately, displays -0 for -0
|
Tue 21 Jul 2015 05:58:08 PM UTC, comment #3:
Thanks, I guess they have made a special case when the second argument is 1. Octave already has this for the special case where the second argument is 0 so it would be easy to add.
Could you try some other tests to verify corner cases?
|
Tue 21 Jul 2015 05:18:42 PM UTC, comment #2:
I'm using MATLAB Version: 8.4.0.150421 (R2014b). Note that MATLAB
displays -0 as 0. So I use atan2d to test for the sign:
>> atan2d(rem(-0,1),-1)
ans =
-180
|
Tue 21 Jul 2015 03:40:00 PM UTC, comment #1:
Which version of Matlab are you using that shows this behavior? Most of the time Matlab is aggressive about normalizing negative zeros to positive zeros.
|
Mon 20 Jul 2015 02:02:06 PM UTC, original submission:
The subject line says it all. Most implementations of this
functionality (MATLAB, C, C++) return a result with the same
sign as the first argument. Octave should too.
(This may be related to bug #45481.)
|