How does the mod function compensate for floating point round off?

17 ビュー (過去 30 日間)
Joel Handy
Joel Handy 2022 年 9 月 19 日
コメント済み: Bobby Cheng 2022 年 9 月 20 日
The documentation for the mod function states, "mod attempts to compensate for floating-point round-off effects to produce exact integer results when possible." What exactly does this mean?

採用された回答

Joel Handy
Joel Handy 2022 年 9 月 20 日
Answering my own question. I wrapped the mod function and generated c code. if the quotient is within eps * quotient of bieing an integer value, the mod function returns zero.
  2 件のコメント
John D'Errico
John D'Errico 2022 年 9 月 20 日
x = 1 + eps;
mod(x,1)
ans = 2.2204e-16
Does that suggest your answer may have a subtle flaw? There is no number repersentable in MATLAB between 1 and (1 + eps).
Bobby Cheng
Bobby Cheng 2022 年 9 月 20 日
Two things:
1) The compensation only happens when the second input is not of integer values. That is why mod(1+eps,1) returns eps. Otherwise it is what Joel said.
2) I can see there is room for improvement for MATLAB documentation to better clarify this.

サインインしてコメントする。

その他の回答 (3 件)

Matt J
Matt J 2022 年 9 月 19 日
編集済み: Matt J 2022 年 9 月 19 日
I suspect it is just meant to tell you that it doesn't do a naive computation like in modNaive below.
m=1000*pi; n=pi;
mod(m,n)
ans = 0
modNaive(m,n)
ans = 3.1416
It isn't something you should try to rely on, though. There are definitely cases where the result won't be an exact integer, even when it's clearly what would be ideal, e.g.,
mod(117*sqrt(1001)+1,sqrt(1001))-1
ans = -3.5527e-14
function out=modNaive(m,n)
out=m-floor(m/n)*n;
end
  6 件のコメント
Matt J
Matt J 2022 年 9 月 20 日
編集済み: Matt J 2022 年 9 月 20 日
@Joel Handy It is additional logic, and we don't know authoritatively what it is. However, the only thing it could rationally be doing is assessing a tolerance on the error,
err=abs(m/n-round(m/n))
If err<tolerance, it is assumed that m/n is intended to be an integer and the output of mod defaults to zero. Otherwise, mod is computed as in modNaive.
Matt J
Matt J 2022 年 9 月 20 日
I 'm not sure I can agree, mod must be identical sequence of instructions based on IEEE 754 division and remainder. Any CPU architecture should give identical result.
That may apply to the operations executed within mod itself. However, the preceding computations that generated the inputs to mod may have different floating point errors affecting them. That would be enough to generate different results in the neighborhood of mod's discontinuities.

サインインしてコメントする。


Bruno Luong
Bruno Luong 2022 年 9 月 20 日
編集済み: Bruno Luong 2022 年 9 月 20 日
I try to replicate MATLAB mod ith this function, it seems working well for 2 examples, no warranty beside that.
x=(rand(1,1e6)-0.5)*(10*pi);
all(rmod(x,pi) == mod(x,pi))
ans = logical
1
x = (-1000:1000)*pi;
all(rmod(x,pi) == mod(x,pi))
ans = logical
1
function r = rmod(x, a)
k = round(x/a);
r = x - a*k;
r(abs(r) < eps(x)) = 0; % EDIT test probably non effective
r(r < 0) = r(r < 0) + a;
end

Bruno Luong
Bruno Luong 2022 年 9 月 20 日
Second version, correction under stricter condition than in the first version
function r = rmod2(x, a)
k = round(x/a);
r = x - a*k;
r(abs(r) < eps(a)) = 0;
r(r < 0) = r(r < 0) + a;
end
  1 件のコメント
Bruno Luong
Bruno Luong 2022 年 9 月 20 日
I think my test with espsilon is actually useless, this seem to match mod, unless someone can come with a counter example
function r = rmod(x, a)
k = round(x/a);
r = x - a*k;
r(r < 0) = r(r < 0) + a;
end

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeMatrix Indexing についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by