Azzera filtri
Azzera filtri

num2str weird behavior with decimal input....

4 visualizzazioni (ultimi 30 giorni)
Gabriel
Gabriel il 10 Mar 2015
Commentato: Stephen23 il 11 Mar 2015
I am trying to get matlab to output a string of length 2 for any number between 0 and 99. In that particular case, my input is between 0 and 0.99. So I tryed num2str(X*100,'%0.2u') where X is my input. Now, here is what happens:
X = 0.03 => num2str(X*100,'%0.2u'): ans = '03'
X = 0.05 => num2str(X*100,'%0.2u'): ans = '05'
X = 0.08 => num2str(X*100,'%0.2u'): ans = '08'
X = 0.1 => num2str(X*100,'%0.2u'): ans = '10'
but
X = 0.07 => num2str(X*100,'%0.2u'): ans ='7.00e+00'
I am working with Matlab 2014b and have exactly that problem on two different computers. Does someone understand why and what can be done?
Thank you very much!
  3 Commenti
Jan
Jan il 10 Mar 2015
Conclusion of the given answers: This behavior is not weird, but expected and wanted. You've expected something else, but here only these expectations are not suiting.
Stephen23
Stephen23 il 11 Mar 2015
@Gabriel: rather than convert the number class, just use a more suitable format, as I explained in my answer.

Accedi per commentare.

Risposte (3)

Stephen23
Stephen23 il 10 Mar 2015
Modificato: Stephen23 il 10 Mar 2015
As explained by Michael Haderlein, this is caused by non-integer values resulting in the default '%e' format being used. For better control without requiring that the variables are first converted to an integer class or rounded (slow!), consider simply using the format '%02.0f' instead:
>> X = [0.03; 0.05; 0.08; 0.07];
>> fprintf('%02.0f\n',100*X)
03
05
08
07
Note that I used fprintf , both sprintf and num2str use the same format strings as well, but num2str is the slowest.

Michael Haderlein
Michael Haderlein il 10 Mar 2015
Modificato: Michael Haderlein il 10 Mar 2015
You already pointed to the correct reason with your comment. It's basically about floating point arithmeticts.
>> [0.03*100-3;
0.05*100-5;
0.08*100-8;
0.07*100-7]
ans =
1.0e-15 *
0
0
0
0.8882
You see that for the computer 0.07*100 is not 7 (obviously the binary representation of 0.07 is rather poor - but there are similar cases for other floating point numbers).
In the Matlab help (I checked the sprintf documentation, but it will be in other functions, too) it is written:
If you specify a conversion that does not fit the data, such as a string conversion for a numeric value, MATLAB® overrides the specified conversion, and uses %e.
That's exactly what happens here. Your fix is fine therefore, because it's exactly addressing this issue. You might think about using uint16/uint32 as converted data type because that's what you use in your string format, but that's not too important, I think.

James Tursa
James Tursa il 10 Mar 2015
FYI, here are the exact decimal conversions of the IEEE double floating point bit patterns in question:
>> num2strexact([.01,.02,.03,.04,.05,.06,.07,.08,.09,.10]')
ans =
'1.000000000000000020816681711721685132943093776702880859375e-2'
'2.00000000000000004163336342344337026588618755340576171875e-2'
'2.99999999999999988897769753748434595763683319091796875e-2'
'4.0000000000000000832667268468867405317723751068115234375e-2'
'5.000000000000000277555756156289135105907917022705078125e-2'
'5.9999999999999997779553950749686919152736663818359375e-2'
'7.0000000000000006661338147750939242541790008544921875e-2'
'8.000000000000000166533453693773481063544750213623046875e-2'
'8.99999999999999966693309261245303787291049957275390625e-2'
'0.1000000000000000055511151231257827021181583404541015625'
>> num2strexact([.01,.02,.03,.04,.05,.06,.07,.08,.09,.10]'*100)
ans =
'1'
'2'
'3'
'4'
'5'
'6'
'7.00000000000000088817841970012523233890533447265625'
'8'
'9'
'1e1'
You can find num2strexact here:

Categorie

Scopri di più su Matrices and Arrays in Help Center e File Exchange

Tag

Prodotti

Community Treasure Hunt

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

Start Hunting!

Translated by