floating point - Why is 24.0000 not equal to 24.0000 in MATLAB? -
i writing program need delete duplicate points stored in matrix. problem when comes check whether points in matrix, matlab can't recognize them in matrix although exist.
in following code, intersections
function gets intersection points:
[points(:,1), points(:,2)] = intersections(... obj.modifiedvgvertices(1,:), obj.modifiedvgvertices(2,:), ... [vertex1(1) vertex2(1)], [vertex1(2) vertex2(2)]);
the result:
>> points points = 12.0000 15.0000 33.0000 24.0000 33.0000 24.0000 >> vertex1 vertex1 = 12 15 >> vertex2 vertex2 = 33 24
two points (vertex1
, vertex2
) should eliminated result. should done below commands:
points = points((points(:,1) ~= vertex1(1)) | (points(:,2) ~= vertex1(2)), :); points = points((points(:,1) ~= vertex2(1)) | (points(:,2) ~= vertex2(2)), :);
after doing that, have unexpected outcome:
>> points points = 33.0000 24.0000
the outcome should empty matrix. can see, first (or second?) pair of [33.0000 24.0000]
has been eliminated, not second one.
then checked these 2 expressions:
>> points(1) ~= vertex2(1) ans = 0 >> points(2) ~= vertex2(2) ans = 1 % <-- means 24.0000 not equal 24.0000?
what problem?
more surprisingly, made new script has these commands:
points = [12.0000 15.0000 33.0000 24.0000 33.0000 24.0000]; vertex1 = [12 ; 15]; vertex2 = [33 ; 24]; points = points((points(:,1) ~= vertex1(1)) | (points(:,2) ~= vertex1(2)), :); points = points((points(:,1) ~= vertex2(1)) | (points(:,2) ~= vertex2(2)), :);
the result expected:
>> points points = empty matrix: 0-by-2
the problem you're having relates how floating-point numbers represented on computer. more detailed discussion of floating-point representations appears towards end of answer (the "floating-point representation" section). tl;dr version: because computers have finite amounts of memory, numbers can represented finite precision. thus, accuracy of floating-point numbers limited number of decimal places (about 16 significant digits double-precision values, default used in matlab).
actual vs. displayed precision
now address specific example in question... while 24.0000
, 24.0000
displayed in same manner, turns out differ small decimal amounts in case. don't see because matlab only displays 4 significant digits default, keeping overall display neat , tidy. if want see full precision, should either issue format long
command or view hexadecimal representation of number:
>> pi ans = 3.1416 >> format long >> pi ans = 3.141592653589793 >> num2hex(pi) ans = 400921fb54442d18
initialized values vs. computed values
since there finite number of values can represented floating-point number, it's possible computation result in value falls between 2 of these representations. in such case, result has rounded off 1 of them. introduces small machine-precision error. means initializing value directly or computation can give different results. example, value 0.1
doesn't have exact floating-point representation (i.e. gets rounded off), , end counter-intuitive results due way round-off errors accumulate:
>> a=sum([0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1]); % sum 10 0.1s >> b=1; % initialize 1 >> == b ans = logical 0 % unequal! >> num2hex(a) % let's check hex representation confirm ans = 3fefffffffffffff >> num2hex(b) ans = 3ff0000000000000
how correctly handle floating-point comparisons
since floating-point values can differ small amounts, comparisons should done checking values within range (i.e. tolerance) of 1 another, opposed equal each other. example:
a = 24; b = 24.000001; tolerance = 0.001; if abs(a-b) < tolerance, disp('equal!'); end
will display "equal!".
you change code like:
points = points((abs(points(:,1)-vertex1(1)) > tolerance) | ... (abs(points(:,2)-vertex1(2)) > tolerance),:)
floating-point representation
a overview of floating-point numbers (and ieee 754 standard floating-point arithmetic) what every computer scientist should know floating-point arithmetic david goldberg.
a binary floating-point number represented 3 integers: sign bit s
, significand (or coefficient/fraction) b
, , exponent e
. for double-precision floating-point format, each number represented 64 bits laid out in memory follows:
the real value can found following formula:
this format allows number representations in range 10^-308 10^308. matlab can these limits realmin
, realmax
:
>> realmin ans = 2.225073858507201e-308 >> realmax ans = 1.797693134862316e+308
since there finite number of bits used represent floating-point number, there many finite numbers can represented within above given range. computations result in value doesn't match 1 of these finite representations, values must rounded off. these machine-precision errors make evident in different ways, discussed in above examples.
in order better understand these round-off errors it's useful @ relative floating-point accuracy provided function eps
, quantifies distance given number next largest floating-point representation:
>> eps(1) ans = 2.220446049250313e-16 >> eps(1000) ans = 1.136868377216160e-13
notice precision relative size of given number being represented; larger numbers have larger distances between floating-point representations, , have fewer digits of precision following decimal point. can important consideration calculations. consider following example:
>> format long % display full precision >> x = rand(1, 10); % 10 random values between 0 , 1 >> = mean(x) % take mean = 0.587307428244141 >> b = mean(x+10000)-10000 % take mean @ different scale, shift b = 0.587307428244458
note when shift values of x
range [0 1]
range [10000 10001]
, compute mean, subtract mean offset comparison, value differs last 3 significant digits. illustrates how offset or scaling of data can change accuracy of calculations performed on it, has accounted problems.
Comments
Post a Comment