Why does the modulo function seem to break for large numbers?

21 ビュー (過去 30 日間)
Kiran KC
Kiran KC 2021 年 11 月 5 日
コメント済み: Rik 2021 年 11 月 5 日
For part of a function I am writing that tests whether an input number is an integer.
The answer should be zero, because for any integer n, (n*10)/10 = n , Therefore, mod(n*10,10) = 0
But in this case of very large numbers (like the one in the screenshot above), it does not work. I would appreciate any explanations as to why this is and/or how to solve this problem?

採用された回答

Stephen23
Stephen23 2021 年 11 月 5 日
編集済み: Stephen23 2021 年 11 月 5 日
You used a binary floating point number whose precision is limited to around 15-16 significant decimal digits.
The output of MOD is "correct" (even if those end digits are effectively noise):
format bank
x = 290384798012501645096234 % check the value stored in memory:
x =
290384798012501642969088.00
y = x*10 % and also the value stored after that multiplication:
y =
2903847980125016228364288.00
mod(y,10)
ans =
8.00
You could use the symbolic toolbox, which supports arbitrary integer lengths:
x = sym('290384798012501645096234')
x = 
290384798012501645096234
y = x*10
y = 
2903847980125016450962340
mod(y,10)
ans = 
0
Another approach is to download this toolbox:
  1 件のコメント
Kiran KC
Kiran KC 2021 年 11 月 5 日
Makes sense, thank you for the detailed answer!

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

その他の回答 (1 件)

Steven Lord
Steven Lord 2021 年 11 月 5 日
For sufficiently large numbers, not all numbers in that vicinity are representable in IEEE double precision. What's the distance between your number and the next largest number?
x = 290384798012501645096234;
eps(x)
ans = 33554432
So if I were to add a million to x, I still haven't gotten to the next largest number.
y = x + 1e6;
y == x % true
ans = logical
1
The same were to hold if I added a number that you would expect changes the last digit of x. In fact it's negligible enough relative to x that it doesn't change x at all.
y = x + 1234567;
y == x
ans = logical
1
If you want to work with numbers that large and represent each number in that vicinity, you're going to need to work symbolically.
s = sym('290384798012501645096234');
t = s + 1e6;
isAlways(s == t) % false
ans = logical
0
t = s + 1234567;
isAlways(s == t) % false
ans = logical
0
mod(s, 10)
ans = 
4
  3 件のコメント
Steven Lord
Steven Lord 2021 年 11 月 5 日
There is not, each Answers post allows at most one accepted answer. If they both helped you vote for one (or both) and accept one of them of your choice.
Rik
Rik 2021 年 11 月 5 日
That is not intended to be possible (it can happen in some rare cases where servers are slow to update, creating a sort of race condition, I don't know if this is still possible).
You can click the vote button and write a comment with a thank you.

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

カテゴリ

Help Center および File ExchangeNumber Theory についてさらに検索

製品


リリース

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by