Why am I receiving 1 full integer less when dividing using fix()

4 views (last 30 days)
Jonathan Perry on 21 Jul 2016
Edited: John BG on 22 Jul 2016
So I'm working on Cody, and am trying to make a dollar amount (a) split into an array (change) in paper and coin money. I have it set up to divide the given amount (a) by each of the elements one x one in (change) using the function fix() to eliminate remainders. I then take the remainder after the division and rerun the for loop over the remainder.
This works perfectly until the final loop, done on the 0.01 element in (change). In this example the final return should be 4, but I repeatedly receive 3. Can anyone help me figure why this is the case?
change = [100 50 20 10 5 2 1 0.5 0.25 0.1 0.05 0.01];
a = 10035.99;
for i = 1:size(change,2)
b(1,i) = fix(a/(change(i)))
a = mod(a,change(i))
end
b(2,:) = change

Azzi Abdelmalek on 22 Jul 2016
Edited: Azzi Abdelmalek on 22 Jul 2016
In your case, let us run the code until a=0.04
change = [100 50 20 10 5 2 1 0.5 0.25 0.1 0.05 0.01];
b=zeros(2,numel(change))
a = 10035.99;
for i = 1:numel(change)-1
b(1,i) = fix(a/(change(i)))
a = mod(a,change(i))
end
Then test
a==0.04
You see that a is not equal to 0.04, you can check that it's less then 0.04, that's why you get the result 3. This is du to calculations errors.
To fix the problem use round function instead of fix function
change = [100 50 20 10 5 2 1 0.5 0.25 0.1 0.05 0.01];
a = 10035.99;
b=zeros(2,numel(change))
for i = 1:numel(change)
b(1,i) = round(a/(change(i)))
a = mod(a,change(i))+1e-6
end
b(2,:) = change

John BG on 21 Jul 2016
Edited: John BG on 22 Jul 2016
Hi Jonathan
1.-
..
for i = 1:size(change,2)
in this case you don't need size(change,2), size(change) is enough because MATLAB recognises that there is only one dimension >1.
2.- The same applies to the variable you intend to use to collect the results, b, you are indexing b(1,i) but with indexing b(i) would be enough.
3.- Azzi Abdelmalek is right, the main error is using fix(), instead use round(), or you can also use floor()
4.- And
..
b(2,:) = change
don't see use either.
So, you write 'it works perfectly until the final loop' (?) yet when I run your lines the variable you intend to use to collect the result, b, is empty, so, it's not that 'doesn't work perfectly', simply, it doesn't work.
The following works, I renamed your 'b' to 'change', seems reasonable, doesn't it? and your 'change' I call it 'base', as you are actually decomposing the amount into a base, aren't you have a look:
a=randi([1 2000000],1,1);a=a/100
base = [100 50 20 10 5 2 1 0.5 0.25 0.1 0.05 0.01];
change=zeros(1,length(base))
a2=a;
% for k=1:1:size(base)
k=1
while k<length(base)+1
while a2/base(k)>1
a2=a2-base(k);
change(k)=change(k)+1;
end
k=k+1
end
change
So, Jonathan, having commented where your code doesn't work,