Conditional loop to loop until result is an integer.

I am trying to create a script that will give me the value for an integer 'n' such that 2n/k = a where a is also an integer. K varies from 0.01 to 1 in increments of 0.01. I am then using this result to find delta where delta = 2*pi*n. The first few results are correct when verified with a calculator. The 6th and 7th gives results 9 and 77 as the lowest value for n for k=0.06 and 0.07 where a is an integer however from a calculator it can be seen that the values 3 and 7 for n would also return an integer. For k=0.12 the script cannot find a value for n and runs infinitely despite the fact that n=3 would an integer value for a (2*3/0.12 = 50)
Currently I have
k(1)=0.01;
n(1)=1;
for i=1:100;
a(i)=(2*n(i))/k(i);
while floor(a(i))~=ceil(a(i))
n(i)=n(i)+1;
a(i)=(2*n(i))/k(i);
end
deltamax(i)=2*pi*n(i);
k(i+1)=k(i)+0.01;
n(i+1)=1;
end

 採用された回答

Stephen23
Stephen23 2020 年 12 月 11 日
編集済み: Stephen23 2020 年 12 月 11 日

1 投票

As it is currently implemented that algorithm will not work because it does not take into account the behavior of binary floating point numbers. Most of those fractional values you are working with cannot be represented exactly: in general any operations on them will accumulate floating point error. If you want to see the actual value of 0.12 (or any of the other fractional values) then download this function:
or (depending on your OS and MATLAB version) you can try SPRINTF/FPRINTF:
fprintf('%.42f\n',0.12)
0.119999999999999995559107901499373838305473
Some workarounds to this are that you could:
  1. use symbolic mathematics, or
  2. allow for some tolerance in your numeric calculations and logical operations, or
  3. adjust the algorithm to work only with integer values, e.g. here multiplied by 100 so all values are integers:
k = 12; % 0.12
n = 100; % 1
while mod(2*n/k,10)
n = n+100;
end
n = n/100
n = 3

2 件のコメント

Stephen23
Stephen23 2020 年 12 月 11 日
Your other examples:
k = 6; % 0.06
n = 100; % 1
while mod(2*n/k,10)
n = n+100;
end
n = n/100
n = 3
k = 7; % 0.07
n = 100; % 1
while mod(2*n/k,10)
n = n+100;
end
n = n/100
n = 7
ljp8991
ljp8991 2020 年 12 月 11 日
Thanks for this, I implemented the method from your examples into my code and got the desired results.

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

その他の回答 (1 件)

Steven Lord
Steven Lord 2020 年 12 月 11 日
編集済み: Steven Lord 2020 年 12 月 11 日

1 投票

If 2n/k = a and you want to find n and a, rewrite this as 2n/a = k. So you want to return two integer matrices whose ratio is "close to" k. There is a function in MATLAB for this: rat.
[N, D] = rat(0.06)
N = 3
D = 50
Since N is odd, we cannot find n from it (N = 2*n.) If we let a = 2*D, then n is the same as N. (2*n)/a = (2*N)/(2*D) = N/D = k.
n = N
n = 3
a = 2*D
a = 100
[2*n/a; 0.06]
ans = 2×1
0.0600 0.0600
(2*n/a)-0.06 % small or zero
ans = 0
rat accepts a tolerance and if you do not provide one uses one that should probably be sufficient for the problems you've described.

カテゴリ

ヘルプ センター および File ExchangeLoops and Conditional Statements についてさらに検索

質問済み:

2020 年 12 月 11 日

コメント済み:

2020 年 12 月 11 日

Community Treasure Hunt

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

Start Hunting!

Translated by