Why does "mat2str(0.005,90)" return 0.0050000000000000001 in MATLAB?

10 views (last 30 days)
According to the documentation:
"str = mat2str(A) converts matrix A into a string. This string is suitable for input to the eval function such that eval(str) produces the original matrix to within 15 digits of precision."
I found a call to "mat2str" with 90-digit precision in our code -- "mat2str(content, 90)". This actually produces values that are problematic for us (see trace below). We expected "mat2str" to output the exact representation of the input value, but setting the precision parameter too high actually caused a decrease in precision. 
 
If we set the precision parameter to 15, does it guarantee that any input with less than 15 digit after decimal point will be represented correctly in the output string of "mat2str"? If not, what is the guaranteed precision of mat2str(value,15)? 
 
Thanks. 
 
Code:
 
>> mat2str(0.005, 90)
ans =
0.0050000000000000001
>> mat2str(0.005, 17)
ans =
0.0050000000000000001
>> mat2str(0.005, 15)
ans =
0.005
>> mat2str(0.005, 16)
ans =
0.005

Accepted Answer

MathWorks Support Team
MathWorks Support Team on 25 Apr 2014
Double-precision numbers are stored in MATLAB using 64 bits as per the IEEE standard for floating-point arithmetic. With 64 bits in the binary representation, the maximum possible precision in base 10 is 15 to 17 digits. Therefore, it should not matter if 0.05 is represented as a string with more than 15 decimals.
 
The "mat2str" function uses "sprintf" to print a number with n digits. The 1 that appears near the end with "mat2str(0.005,90)" is due to the fact that 0.005 cannot be exactly represented on a computer with 64 bits. However, if we look at the hexadecimal representation of the output of "mat2str", we get the same number:
 
% Set format to hexadecimal
>> format hex
% Convert 0.005 to a string with precision 15 digits
>> s = mat2str(0.005,15)
s =
0.005
>> eval(s)
ans =
3f747ae147ae147b
% Convert 0.05 to a string with precision 90 digits
>> s = mat2str(0.005,90)
s =
0.0050000000000000001
>> eval(s)
ans =
3f747ae147ae147b
 
The string "s" might be different, but the garbage digit at the end does not matter. Only the first 15 digits after the decimal point matter and this is shown by evaluating "s": we obtain the same binary number.
 
Instead of using "mat2str" you could store the exact representation of the number in hexadecimal form. The "num2hex" function converts a double-precision number into its hexadecimal representation as a string. This might be a better solution if you only plan to use it on scalars -- "num2hex" does not work on arrays unlike "mat2str".
  2 Comments
James Tursa
James Tursa on 25 Apr 2014
Edited: MathWorks Support Team on 19 Apr 2021
I don't know if this is still true or not, but sprintf used to behave differently on a PC vs LINUX system for these extended digit cases. So output dependent on it might get slightly different string answers on the different platforms. The following example was done on 32-bit Win7 MATLAB:
>> sprintf('%0.60f',.005)
ans =
0.005000000000000000100000000000000000000000000000000000000000
>> num2strexact(.005)
ans =
5.000000000000000104083408558608425664715468883514404296875e-3
>> num2strexact(.005-eps(.005))
ans =
4.99999999999999923672167057020487845875322818756103515625e-3
num2strexact shows the actual IEEE double numbers that bracket .005, and you can see that MATLAB has indeed picked the nearest one. But the sprintf function does not print out all of these digits even when asked to. LINUX systems used to (and may still do but I can't verify) print out all of the actual digits. Regardless, when converted back to double via eval you still get the original IEEE floating point bit pattern back as the Accepted Answer states. You can find num2strexact here:
Walter Roberson
Walter Roberson on 19 Apr 2021
Historically, there was a point where Windows was quite bad about conversion to full precision (fail!!), and Linux was better but still limited, but the Mac version was perfect.

Sign in to comment.

More Answers (0)

Categories

Find more on Data Type Conversion in Help Center and File Exchange

Products


Release

R2014a

Community Treasure Hunt

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

Start Hunting!