Why does this code generate a mix of integers and doubles?

When I run the following code it generates a mixture of integers and decimal points which I can't use for array indexing.
for j = 0:0.1:3
disp(j*10+1);
end
Output:
1
2
3
4
5
6
7.0000
8
9
10
11
12
13.0000
14
15.0000
16
17
18
19
20
21
22
23
24.0000
25.0000
26
27
28
29.0000
30.0000
31

4 Comments

"Why does this code generate a mix of integers and doubles?"
They are all doubles.
V = 0:0.1:3;
fprintf('%.42f\n',V(7),V(7)*10+1)
0.600000000000000088817841970012523233890533 7.000000000000000888178419700125232338905334
Ok, I understand that, but it seems like Matlab interprets the figures which appear as an integer to be an integer. Why doesn't this work for all of them? When I run the following code
a = zeros(31,1);
for j = 0:0.1:3
a(j*10+1) = j;
end
I get this error:
Array indices must be positive integers or logical values.
Error in untitled (line 5)
a(j*10+1) = j;
which occurs at j = 0.7 and (j*10+1) = 7.0000.
I'm using round() to get around this but I'm just curious if there is a reason why Matlab only treats some of these as integers.
"it seems like Matlab interprets the figures which appear as an integer to be an integer"
MATLAB displays binary floating point numbers with zero fractional part without any trailing fractional digits. The trailing zeros e.g. "X.0000" tells us that the fractional part is not zero (not matter how small it might be).
"Why doesn't this work for all of them?"
Because how floating point error accumulates depends on the values and operations concerned: sometimes it might appear to "cancel out", sometime it might increase. That is simply how binary floating point numbers are.
"I'm just curious if there is a reason why Matlab only treats some of these as integers."
Because only some of them are whole numbers.

Sign in to comment.

 Accepted Answer

In practice you can look on this problem as "good luck" and "bad luck" when it comes to working and not working. The rounding of fixed precision floating-point arithmetic is intricate, look for the blog-posts on these matters by Cleve Moler or Loren Shure (and possibly others). From a practical perspective the rounding-errors might turn up as you expect, but since 0.1 has an infinite expansion in binary you cannot expect it to always give you that result. Therefore when you calculate indices the robust approach is to explicitly handle this by casting your flint-numbers into proper integers with round - then you know that you have made a concious design-choise of how to handle this (hopefully a good design-choise too).
Once uppon a time matlab used to round general floats in matrix-indexing operations which for my application was incredibly convenient, then they changed that rounding-operation to floor instead of round - which I "handled short-term" by adding 1/2 to my indices, the next change was to require integers into the indexing - which forces us to make this design-choise explicitly.
HTH

More Answers (0)

Products

Release

R2022a

Asked:

on 25 May 2022

Commented:

on 25 May 2022

Community Treasure Hunt

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

Start Hunting!