Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Matlab floating point

  1. Jul 23, 2010 #1

    Pythagorean

    User Avatar
    Gold Member

    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. jcsd
  3. Jul 23, 2010 #2

    Mark44

    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.
     
  4. Jul 23, 2010 #3

    Pythagorean

    User Avatar
    Gold Member

    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?
     
  5. Jul 23, 2010 #4

    Pythagorean

    User Avatar
    Gold Member

    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
  6. Jul 24, 2010 #5

    Mark44

    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.
     
  7. Jul 26, 2010 #6

    Pythagorean

    User Avatar
    Gold Member

    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
     
  8. Jul 26, 2010 #7
    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 :smile:
     
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook