MATLAB Answers

Translated by

このページのコンテンツは英語から自動翻訳されています。自動翻訳をオフにする場合は「<a class="turn_off_mt" href="#">ここ</a>」をクリックしてください。

0

Is there a way to configure the %d in fprintf function to use exponential notation when writing to a text file?

Bilge Kaan Atay さんによって質問されました 2019 年 1 月 30 日
最新アクティビティ Bilge Kaan Atay さんによって コメントされました 2019 年 1 月 30 日
As far as I can see, when the fprintf command is used with %d MATLAB is deciding to use exponential notation if the number has more digits than 19. This situation can be observed with the code given in below.
%This code writes 1234567891234567936 to the text file.
not = fopen('gemSonuc.txt','w');
a=123456789123456789;
fprintf(not,'%d',a);
%This code writes 1.234568e+19 to the text file.
not = fopen('gemSonuc.txt','w');
a=12345678912345678912;
fprintf(not,'%d',a);
My main question is: Is there a way to configure this digit rule?
For further details here is the complete code:
%Constants
combs = [8 15 16 32 64 128 213 256 367 512 971 1024 1912 2048 4096 8192 16384 32768 65536 ...
131072 262144 724411 1048576 1451480 2097152 3070075];
u = length(combs);
step = zeros(10, u); % preallocating
temp = 110592;
%Calculating
n=1;
while(n<10)
for i=1:u
step(n+1, i) = temp*combs(i);
end
temp = step(n+1,u);
n=n+1;
end
step(1,:) = combs;
%Writing to a Text File
not = fopen('gemSonuc.txt','w');
fprintf(not, 'Baslangic (2048 spec) = 110592\n');
for k=1:n
for l=1:u
fprintf(not,'%21d', step(k,l));
end
fprintf(not, '\n');
end
fclose(not);
fprintf('end of process')
%%%%%%%%%%%% Result written to the file: %%%%%%%%%%%%
%Baslangic (2048 spec) = 110592
% 8 15 16 32 64 128 213 256 367 512 971 1024 1912 2048 4096 8192 16384 32768 65536 131072 262144 724411 1048576 1451480 2097152 3070075
% 884736 1658880 1769472 3538944 7077888 14155776 23556096 28311552 40587264 56623104 107384832 113246208 211451904 226492416 452984832 905969664 1811939328 3623878656 7247757312 14495514624 28991029248 80114061312 115964116992 160522076160 231928233984 339525734400
% 2716205875200 5092886016000 5432411750400 10864823500800 21729647001600 43459294003200 72318981427200 86918588006400 124605944524800 173837176012800 329679488102400 347674352025600 649173204172800 695348704051200 1390697408102400 2781394816204800 5562789632409600 11125579264819200 22251158529638400 44502317059276800 89004634118553600 245956176782438400 356018536474214400 492814812966912000 712037072948428800 1042369469038080000
% 8338955752304640000 1.563554e+19 1.667791e+19 3.335582e+19 6.671165e+19 1.334233e+20 2.220247e+20 2.668466e+20 3.825496e+20 5.336932e+20 1.012141e+21 1.067386e+21 1.993010e+21 2.134773e+21 4.269545e+21 8.539091e+21 1.707818e+22 3.415636e+22 6.831273e+22 1.366255e+23 2.732509e+23 7.551039e+23 1.093004e+24 1.512978e+24 2.186007e+24 3.200152e+24
% 2.560122e+25 4.800229e+25 5.120244e+25 1.024049e+26 2.048098e+26 4.096195e+26 6.816325e+26 8.192390e+26 1.174456e+27 1.638478e+27 3.107348e+27 3.276956e+27 6.118691e+27 6.553912e+27 1.310782e+28 2.621565e+28 5.243130e+28 1.048626e+29 2.097252e+29 4.194504e+29 8.389008e+29 2.318226e+30 3.355603e+30 4.644957e+30 6.711206e+30 9.824708e+30
% 7.859766e+31 1.473706e+32 1.571953e+32 3.143907e+32 6.287813e+32 1.257563e+33 2.092663e+33 2.515125e+33 3.605668e+33 5.030251e+33 9.539791e+33 1.006050e+34 1.878484e+34 2.012100e+34 4.024200e+34 8.048401e+34 1.609680e+35 3.219360e+35 6.438721e+35 1.287744e+36 2.575488e+36 7.117127e+36 1.030195e+37 1.426037e+37 2.060391e+37 3.016259e+37
% 2.413007e+38 4.524389e+38 4.826014e+38 9.652029e+38 1.930406e+39 3.860812e+39 6.424632e+39 7.721623e+39 1.106967e+40 1.544325e+40 2.928788e+40 3.088649e+40 5.767087e+40 6.177299e+40 1.235460e+41 2.470919e+41 4.941839e+41 9.883678e+41 1.976736e+42 3.953471e+42 7.906942e+42 2.185011e+43 3.162777e+43 4.378040e+43 6.325554e+43 9.260142e+43
% 7.408113e+44 1.389021e+45 1.481623e+45 2.963245e+45 5.926491e+45 1.185298e+46 1.972410e+46 2.370596e+46 3.398472e+46 4.741192e+46 8.991597e+46 9.482385e+46 1.770539e+47 1.896477e+47 3.792954e+47 7.585908e+47 1.517182e+48 3.034363e+48 6.068726e+48 1.213745e+49 2.427491e+49 6.708148e+49 9.709962e+49 1.344091e+50 1.941992e+50 2.842933e+50
% 2.274346e+51 4.264399e+51 4.548693e+51 9.097385e+51 1.819477e+52 3.638954e+52 6.055447e+52 7.277908e+52 1.043356e+53 1.455582e+53 2.760488e+53 2.911163e+53 5.435688e+53 5.822327e+53 1.164465e+54 2.328931e+54 4.657861e+54 9.315722e+54 1.863144e+55 3.726289e+55 7.452578e+55 2.059452e+56 2.981031e+56 4.126460e+56 5.962062e+56 8.728017e+56
% 6.982414e+57 1.309203e+58 1.396483e+58 2.792966e+58 5.585931e+58 1.117186e+59 1.859068e+59 2.234372e+59 3.203182e+59 4.468745e+59 8.474905e+59 8.937490e+59 1.668797e+60 1.787498e+60 3.574996e+60 7.149992e+60 1.429998e+61 2.859997e+61 5.719993e+61 1.143999e+62 2.287997e+62 6.322672e+62 9.151989e+62 1.266854e+63 1.830398e+63 2.679567e+63
I want to write the third and the fourth line of table (which are start with 2716205875200 and 8338955752304640000 values) in exponential notation without changing the first and the second line. This is why I don't use %e or %g in frpintf code.
The only solution I found is the code given in the below:
for k=1:2
for l=1:u
fprintf(not,'%21d', step(k,l));
end
fprintf(not, '\n');
end
for k=1+2:n
for l=1:u
fprintf(not,'%21e', step(k,l));
end
fprintf(not, '\n');
end
%%%%%%%%%%%% Result written to the file: %%%%%%%%%%%%
%Baslangic (2048 spec) = 110592
% 8 15 16 32 64 128 213 256 367 512 971 1024 1912 2048 4096 8192 16384 32768 65536 131072 262144 724411 1048576 1451480 2097152 3070075
% 884736 1658880 1769472 3538944 7077888 14155776 23556096 28311552 40587264 56623104 107384832 113246208 211451904 226492416 452984832 905969664 1811939328 3623878656 7247757312 14495514624 28991029248 80114061312 115964116992 160522076160 231928233984 339525734400
% 2.716206e+12 5.092886e+12 5.432412e+12 1.086482e+13 2.172965e+13 4.345929e+13 7.231898e+13 8.691859e+13 1.246059e+14 1.738372e+14 3.296795e+14 3.476744e+14 6.491732e+14 6.953487e+14 1.390697e+15 2.781395e+15 5.562790e+15 1.112558e+16 2.225116e+16 4.450232e+16 8.900463e+16 2.459562e+17 3.560185e+17 4.928148e+17 7.120371e+17 1.042369e+18
% 8.338956e+18 1.563554e+19 1.667791e+19 3.335582e+19 6.671165e+19 1.334233e+20 2.220247e+20 2.668466e+20 3.825496e+20 5.336932e+20 1.012141e+21 1.067386e+21 1.993010e+21 2.134773e+21 4.269545e+21 8.539091e+21 1.707818e+22 3.415636e+22 6.831273e+22 1.366255e+23 2.732509e+23 7.551039e+23 1.093004e+24 1.512978e+24 2.186007e+24 3.200152e+24
% 2.560122e+25 4.800229e+25 5.120244e+25 1.024049e+26 2.048098e+26 4.096195e+26 6.816325e+26 8.192390e+26 1.174456e+27 1.638478e+27 3.107348e+27 3.276956e+27 6.118691e+27 6.553912e+27 1.310782e+28 2.621565e+28 5.243130e+28 1.048626e+29 2.097252e+29 4.194504e+29 8.389008e+29 2.318226e+30 3.355603e+30 4.644957e+30 6.711206e+30 9.824708e+30
% 7.859766e+31 1.473706e+32 1.571953e+32 3.143907e+32 6.287813e+32 1.257563e+33 2.092663e+33 2.515125e+33 3.605668e+33 5.030251e+33 9.539791e+33 1.006050e+34 1.878484e+34 2.012100e+34 4.024200e+34 8.048401e+34 1.609680e+35 3.219360e+35 6.438721e+35 1.287744e+36 2.575488e+36 7.117127e+36 1.030195e+37 1.426037e+37 2.060391e+37 3.016259e+37
% 2.413007e+38 4.524389e+38 4.826014e+38 9.652029e+38 1.930406e+39 3.860812e+39 6.424632e+39 7.721623e+39 1.106967e+40 1.544325e+40 2.928788e+40 3.088649e+40 5.767087e+40 6.177299e+40 1.235460e+41 2.470919e+41 4.941839e+41 9.883678e+41 1.976736e+42 3.953471e+42 7.906942e+42 2.185011e+43 3.162777e+43 4.378040e+43 6.325554e+43 9.260142e+43
% 7.408113e+44 1.389021e+45 1.481623e+45 2.963245e+45 5.926491e+45 1.185298e+46 1.972410e+46 2.370596e+46 3.398472e+46 4.741192e+46 8.991597e+46 9.482385e+46 1.770539e+47 1.896477e+47 3.792954e+47 7.585908e+47 1.517182e+48 3.034363e+48 6.068726e+48 1.213745e+49 2.427491e+49 6.708148e+49 9.709962e+49 1.344091e+50 1.941992e+50 2.842933e+50
% 2.274346e+51 4.264399e+51 4.548693e+51 9.097385e+51 1.819477e+52 3.638954e+52 6.055447e+52 7.277908e+52 1.043356e+53 1.455582e+53 2.760488e+53 2.911163e+53 5.435688e+53 5.822327e+53 1.164465e+54 2.328931e+54 4.657861e+54 9.315722e+54 1.863144e+55 3.726289e+55 7.452578e+55 2.059452e+56 2.981031e+56 4.126460e+56 5.962062e+56 8.728017e+56
% 6.982414e+57 1.309203e+58 1.396483e+58 2.792966e+58 5.585931e+58 1.117186e+59 1.859068e+59 2.234372e+59 3.203182e+59 4.468745e+59 8.474905e+59 8.937490e+59 1.668797e+60 1.787498e+60 3.574996e+60 7.149992e+60 1.429998e+61 2.859997e+61 5.719993e+61 1.143999e+62 2.287997e+62 6.322672e+62 9.151989e+62 1.266854e+63 1.830398e+63 2.679567e+63
I would like the learn that if there is a way to set the digit rule for exponential notation using frpintf with %d or not.

  0 件のコメント

サインイン to comment.

2 件の回答

回答者: Rik Wisselink
2019 年 1 月 30 日
編集済み: Rik Wisselink
2019 年 1 月 30 日
 採用された回答

It looks like this might have something to do with flintmax, which would mean there would be no way to change this. This value is 2^53 for doubles, which works out to 9007199254740992 (so just under 17 digits). If I try writing more digits, my copy of Matlab starts rounding. I also observe the conversion to exponential notation at 20 digits. Hidden in the large doc for fprintf, you can find this:
If you specify a conversion that does not fit the data, such as a text conversion for a numeric value,
MATLAB overrides the specified conversion, and uses %e.
Example: '%s' converts pi to 3.141593e+00.
So apparently, Matlab does not consider such large values to be integers anymore, which makes them not fit the d flag, which causes the conversion to exponential.
What you can do, is either preproces to a string, or dynamically choosing a format specificiation based on your value. You can either compare to flintmax, or use log10() to find the number of digits. (These two are not equivalent.)
%replace this:
%fprintf(not,'%21d', step(k,l));
%before the loop:
FormatSpec={'%21d','%21e'};
NumberOfDigits=@(x) 1+floor(log10(x));
%in the loop
val=step(k,l)
fprintf(not,FormatSpec{1+(val>flintmax)}, val);
%or:
%fprintf(not,FormatSpec{1+(NumberOfDigits(val)>19)}, val);

  1 件のコメント

The information you've written explains this situation. FormatSpec option is worked well for me. In addition, basically one can use val>number (for example in my question this should be number=1e12) in fprintf code without using flintmax or NumberOfDigits.
I prefer NumberOfDigits. Thank you for your answer. It helped me a lot.

サインイン to comment.


回答者: Walter Roberson
2019 年 1 月 30 日

Use %21.12g .
>> sprintf('%21.12g\n', [339525734400, 2716205875200])
ans =
' 339525734400
2.7162058752e+12
'

  0 件のコメント

サインイン to comment.



Translated by