# Matlab floating point

1. Jul 23, 2010

### Pythagorean

so I make a vector:

V3 = [15.05:.05:15.15];
V3c = [14.75:.05:15.15];

find(V3c == Vc(2))

and I get nothing (no matches)

apparently, when matlab constructed V3, it did so such that:
V3(2) == 15.10000000000001
and
V3c(8) == 15.10000000000000

what's the deal?

My cheap way around this is:

V3 = fix(V3*1000)/1000

so I multiply by 1000, shave off the remaining decimals, and divide by 1000, but this doesn't seem robust to me. Is there a better way to handle this floating point difference?

2. Jul 23, 2010

### Staff: Mentor

Certain decimal fractions have computer representations that are only approximate, due to the nature of floating point representations. This isn't something that is specific to matlab, but is present in programming languages that store floating points numbers in binary form.

Decimal fractions that involve 1/2, 1/4, 1/8, 1/16, ... and combinations of them (such as 3/8 = 1/4 + 1/8) have binary representations that are exact. Decimal fractions that involve 1/5, 1/10, and so on have representations that are not exact, because the complete binary representation would require an infinite number of bits. This is similar to the situation with the fraction 1/3 in base-10. The decimal fraction is 0.33333... with an infinite number of 3's. If you truncate the representation, you get a value that is only close to 1/3.

Likewise, the binary representation of 1/10 has an infinitely long binary fraction representation. Since there are only a relatively few bits available (64, typically), the representation is only close to 1/10.

3. Jul 23, 2010

### Pythagorean

Thank you for your response. I understand the concept of floating point numbers. Why does matlab represent 15.1 in two different ways though, and what command can I use to force it to use the same method to define 15.1 the same way in both variables?

4. Jul 23, 2010

### Pythagorean

found a function that pretty much does what I do, only makes the decimal place an input.
from:
[URL]http://home.online.no/~pjacklam[/URL]/matlab/software/util/fullindex.html[/URL]

[CODE]function y = fixdec(x, n)
%FIXDEC Round towards zero with a specified number of decimals.
%
% Y = FIXDEC(X, N) rounds the elements of X to N decimals.
%
% For instance, fixdec(10*sqrt(2) + i*pi/10, 4) returns 14.1421 + 0.3141i
%
% See also: FIX, FLOOR, CEIL, ROUND, FIXDIG, ROUNDDEC, ROUNDDIG.

% Author: Peter J. Acklam
% Time-stamp: 2004-09-22 20:08:10 +0200
% E-mail: pjacklam@online.no
% URL: [URL]http://home.online.no/~pjacklam[/URL]

% Check number of input arguments.
error(nargchk(2, 2, nargin));

% Quick exit if either argument is empty.
if isempty(x) || isempty(n)
y = [];
return
end

% Get size of input arguments.
size_x = size(x);
size_n = size(n);
scalar_x = all(size_x == 1); % True if x is a scalar.
scalar_n = all(size_n == 1); % True if n is a scalar.

% Check size of input arguments.
if ~scalar_x & ~scalar_n & ~isequal(size_x, size_n)
error(['When both arguments are non-scalars they must have' ...
' the same size']);
end

f = 10.^n;
y = fix(x .* f) ./ f;[/CODE]

Last edited by a moderator: Apr 25, 2017
5. Jul 24, 2010

### Staff: Mentor

I don't believe that it is representing 15.1 in two different ways. What you are getting are most likely two different values. Your array Vc contains [15.05, 15.05 + .05, 15.05 + .05 + .05]. Because none of those numbers is exactly representable in 64 bits (or however many matlab uses for a floating point value), it is extremely unlikely that the array contains [15.05, 15.10, 15.15] as you are probably thinking it is.

The other array contains [14.75, 14.75 + .05, 14.75 + .05 + .05, ...], with values ranging from 14.75 (exactly) up to 15.15 (approximately). Because of the addition of numbers that are only close to .05, the next to last value in the array is only close to 15.10.

6. Jul 26, 2010

### Pythagorean

Ah, ok, that adjusts some of my assumption about how floating points are handled (it reminds me of equal tempered tuning!)

My deal was that the difference between the two 15.1's was on the order of e-10, so I was wondering why matlab was so picky and why it can't just read my damn mind about significant digits :P

7. Jul 26, 2010

### cpt_carrot

Instead of using the complicated function above, you could just do something like

abs(V3c-V3(2))<epsilon

where you set epsilon as the tolerance you want to keep. This then returns a logical with ones where the two things were equal.

Hope that helps