Why is floor(2.00000000) giving me a result of 1?

9 views (last 30 days)
Hello everyone,
I have a homework from a MOOC in which for the function I have to "dissect" the digits of a number to see if it is a palindromic number; so far I don't know of any built-in function that does that so I found a way to do it "manually" and it is actually supposed to work if floor() gives me the correct result.
I took a screenshot to post it (the greyed-out part is for the other forum), and there you can see a reproduction fo the calculations being carried out in the function for the problematic case. Why is this happening? I can't find a reason in the documentation.
What I'm doing here is taking a number—12 in this case—and creating a vector with its digits, but I can't go any further for the other digit because the first one is wrong. The variable names are not descriptive, only for me they are, but I think you can see what I'm trying to do.
Thanks in advance.

Accepted Answer

James Tursa
James Tursa on 10 Oct 2016
Edited: James Tursa on 11 Oct 2016
If the number is displaying as 2.0000... on the screen, it isn't exactly 2 but it is close to 2. If a number is exactly 2 it will display as 2 without the 0's past the decimal point printed. So you apparently have done some calculations that result in a number that is very slightly less than 2.
Basically, the result of your floating point calculations cannot be represented exactly in IEEE double precision arithmetic. So this is leading to your problem. E.g., your calculations with the exact decimal conversions shown (note that 1.2 and 0.2 cannot be represented in IEEE double precision exactly):
>> mul = 2*6
mul =
12
>> XVY = 10
XVY =
10
>> XVZ = mul/XVY
XVZ =
1.2000
>> XVZ_1 = floor(XVZ)
XVZ_1 =
1
>> XVW = 1.2 - XVZ_1
XVW =
0.2000
>> T1 = XVW*10
T1 =
2.0000 <-- 0's printing after decimal point means number is not exactly 2
>> floor(T1)
ans =
1
>> num2strexact(XVZ)
ans =
1.1999999999999999555910790149937383830547332763671875
>> num2strexact(XVW)
ans =
0.1999999999999999555910790149937383830547332763671875
>> num2strexact(T1)
ans =
1.999999999999999555910790149937383830547332763671875
  3 Comments
James Tursa
James Tursa on 10 Oct 2016
Edited: James Tursa on 11 Oct 2016
Yes, this is normal MATLAB precision. IEEE double (and single) precision floating point is a binary floating point scheme. As such, the only fractional numbers that can be represented exactly are combinations of inverse powers of 2. That's a fundamental limitation. So 1/2 and 3/8 etc can be represented exactly, but 1/10 and 3/7 no. Anything you do in MATLAB that involves floating point calculations (double or single) will have this limitation. So you will need to use floor or ceil or round or tolerance comparisons in your code as appropriate.
If you have an integer (that is not too large) and you simply want to convert it to a vector of digits, you could do this:
my_digits = num2str(my_number) - '0';
Yes, I wrote num2strexact. It is a mex function, so you need a C compiler to build it. You can find it on the FEX here:
You can also see this link:
Carlos Castillo
Carlos Castillo on 16 Oct 2016
Thank you very much James, I've been busy and couldn't check the links, I will today; that's the answer I needed.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!