Why does Matlab add digits to a code generated vector?

2 Ansichten (letzte 30 Tage)
Brian
Brian am 19 Okt. 2015
Kommentiert: Star Strider am 19 Okt. 2015
I have a simple command that is creating a vector. Test = (51.7:.1:130)' I then iterate through this vector and use the values to search in a list of data that I have. What I find, is that Matlab is actually adding very small numbers to the end of some of my values. For instance 65.5 truly equals 65.500000... However, 65.6 (when you double click) equals 65.600000000000010
I can not think of a logical reason for this behavior. Now, I certainly can go ahead and round the vector before I loop, but that shouldn't be necessary. I'd like to understand why it can't create the vector that I specified.
Thanks for your help, Brian

Akzeptierte Antwort

Star Strider
Star Strider am 19 Okt. 2015
There are two separate processes involved: floating-point approximation error, and the way MATLAB calculated colon-operator generated vectors. If you only want the vector elements to be defined at one decimal place, multiply the vector by 10, use round, floor, or fix, and then divide it by 10:
Test = round(Test*10)/10;
That should provide you with reasonably precise values for your comparison.
  3 Kommentare
Steven Lord
Steven Lord am 19 Okt. 2015
See question 1 in the Mathematics section of the FAQ. Just as you cannot represent the EXACT value of 1/3 with a finite number of decimal places, you cannot represent the EXACT value of 65.6 in IEEE double precision. Why did it work for 65.5? That you CAN exactly represent in IEEE double precision.
And by the way, this is not a MATLAB-specific behavior. You can write a very simple C++ program, or C program, or program in any other language that supports IEEE double precision, to demonstrate the same type of issue. Something quick I whipped up in C++:
#include <iostream>
int main(void)
{
double x = 656.0;
double xOver10 = 65.6;
double y = 65.0;
for(int k = 0; k < 6; k++)
{
y += 0.1;
}
std::cout << "Is xOver10 equal to y? " << (xOver10 == y ? "true" : "false");
std::cout << std::endl;
std::cout << "Their difference is " << xOver10-y << std::endl;
return 0;
}
The equivalent in MATLAB:
x = 656;
xOver10 = 65.6;
y = 65;
for k = 1:6
y = y + 0.1;
end
logicalString = {'false', 'true'};
fprintf('Is xOver10 equal to y? %s\n Their difference is %e\n', ...
logicalString{(xOver10 == y)+1}, xOver10-y);
Star Strider
Star Strider am 19 Okt. 2015
My pleasure.
The floating point approximation error arises in having to represent a decimal number as a string of bits. It’s somewhat analogous to representing 1/3 in decimal digits. The fraction is precise, the decimal approximation, 0.333... with any finite length will never will exactly be equal to the fraction. (In the real world, such word-lengths are finite.) The documentation on Accuracy of Floating Point Data discusses this.
There was a post here a bit ago (that I now cannot locate) that described that MATLAB creates its colon-operator vectors by beginning at each end, adds the step from the beginning of the vector and subtracts it from the end, meeting at the centre of the vector so as to minimise the propagation of errors that would otherwise result if the vector was generated from only one end.
You’re correct to wonder about the ‘simplicity’ of such an instruction, but in the real world applications, things are rarely as simple as they might appear.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Tags

Produkte

Community Treasure Hunt

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

Start Hunting!

Translated by