160 views (last 30 days)

I have both scalar and matrices that I want to print out to the workspace. I'm using num2str() and mat2str() but I am finding that there are some slight precision differences between using format long and num2str(var,32) and mat2str(var,32) and fprintf(%.32f,var).

So if I have a variable, var or a matrix, var, how do I print the actual data it has with no truncation, rounding or data loss?

John D'Errico
on 7 Apr 2017

Edited: John D'Errico
on 7 Apr 2017

I'm not really sure why you want to know this exactly for any matrix of numbers. It will get a bit long to write down the exact values as stored.

You can't really print out the exact value easily, because the exact value will not be representable in a limited number of decimal digits, only about 16 of them.

format long g

a = 1.23

a =

1.23

So a looks like 1.23. But of course it is not. We need to write out 55 digits or so, using a tool like sprintf (or num2str) to show the exact value, since a is really stored in binary form.

sprintf('%0.55f',a)

ans =

1.2299999999999999822364316059974953532218933105468750000

32 digits is NOT sufficient to show the exact value.

num2str(a,32)

ans =

1.2299999999999999822364316059975

See that the actual value of a went on for another 20 decimal digits or so. num2str does work, IF you give it enough room to work.

num2str(a,55)

ans =

1.229999999999999982236431605997495353221893310546875

This does not mean that you can represent all floating point numbers with 50 or so decimal digits, only that when you try to write a decimal fraction in binary form, you will get only an approximation most of the time. In fact, the very next larger floating point number than a that we can represent is

num2str(a+eps(a),55)

ans =

1.2300000000000002042810365310288034379482269287109375

Why have I been using 55 digits here? In fact, we should be able to get away with 53 digits. But 55 adds a safety factor. All doubles in MATLAB are stored using 52 binary bits for the mantissa.

Note that in general, all negative integer powers of 2 (thus 2^(-n))can be written using exactly n digits to the right of the decimal. We can see that here. Each negative power of 2 adds a digit.

2.^-(1:12)'

ans =

0.5

0.25

0.125

0.0625

0.03125

0.015625

0.0078125

0.00390625

0.001953125

0.0009765625

0.00048828125

0.000244140625

Since any mantissa stored in a binary form will be a linear combination of these numbers, then in general, it will take 52 decimal digits to represent a number with 52 binary bits.

James Tursa
on 7 Apr 2017

John D'Errico
on 7 Apr 2017

Roger Stafford
on 7 Apr 2017

If you want the value expressed in decimal form, in the great majority of cases these cannot be given exactly, since all our computers using matlab use binary numbers, not decimal numbers. It is analogous to trying express 1/3 exactly as a decimal fraction - it can’t be done with finitely many decimal places.

I have found that ‘fprintf’ used with floating point precision set to around 18, fprintf(‘%21.18e’), is about as accurate as I ever need to express matlab’s ‘double’ values in decimal.

There is one kind of matlab format that gives an exact value, and that is “format hex”, but it is in the special IEEE 754 hexadecimal format which only the cognoscente can fully appreciate. To remedy this, I wrote a little routine called “binstr” that expresses any double as an exact binary string, and which if it is of interest, can be found at:

http://www.mathworks.com/matlabcentral/answers/79319

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

Start Hunting!
## 0 Comments

Sign in to comment.