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

 Accepted Answer

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 Comments

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
Thanks for this, I implemented the method from your examples into my code and got the desired results.

Sign in to comment.

More Answers (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.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Asked:

on 11 Dec 2020

Commented:

on 11 Dec 2020

Community Treasure Hunt

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

Start Hunting!