Malthe Eisum
Malthe Eisum

Reputation: 189

Formating %e output of sprintf

Is it possible to format the output of sprintf, like following or should I use another function.

Say I have an variable dt= 9.765625e-05 and I want use sprintf to make a string for use when saving say a figure

fig = figure(nfig);
plot(x,y);
figStr = sprintf('NS2d_dt%e',dt);
saveas(fig,figStr,'pdf')

The punctuation mark dot presents me with problems, some systems mistake the format of the file.

using

figStr = sprintf('NS2d_dt%.2e',dt);

then

figStr = NS2d_dt9.77e-05

using

figStr = sprintf('NS2d_dt%.e',dt);

then

figStr = NS2d_dt1e-04

which is not precise enough. I would like something like this
using

figStr = sprintf('NS2d_dt%{??}e',dt);

then

figStr = NS2d_dt9765e-08

Upvotes: 0

Views: 1091

Answers (3)

IKavanagh
IKavanagh

Reputation: 6187

Essentially the only way to get your desired output is with some manipulation of the value or strings. So here's two solutions for you first with some string manipulation and second by manipulating the value. Hopefully, these 2 approaches will help reason out solutions for other problems, particularly the number manipulation.

String Manipulation

Solution

fmt = @(x) sprintf('%d%.0fe%03d', (sscanf(sprintf('%.4e', x), '%d.%de%d').' .* [1 0.1 1]) - [0 0.5 3]);

Explanation

First I use sprintf to print the number in a defined format

>> sprintf('%.4e', dt)
ans =
    9.7656e-05

then sscanf to read it back in making sure to remove the . and e

>> sscanf(sprintf('%.4e', dt), '%d.%de%d').'
ans = 
    9    7656    -5

before printing it back we perform some manipulation of the data to get the correct values for printing

>> (sscanf(sprintf('%.4e', dt), '%d.%de%d').' .* [1 0.1 1]) - [0 0.5 3]
ans = 
    9    765.1    -8

and now we print

>> sprintf('%d%.0fe%03d', (sscanf(sprintf('%.4e', dt), '%d.%de%d').' .* [1 0.1 1]) - [0 0.5 3])
ans =
    9765e-08

Number Manipulation

Solution

orderof = @(x) floor(log10(abs(x)));
fmt = @(x) sprintf('%.0fe%03d', x*(10^(abs(orderof(x))+3))-0.5, orderof(x)-3);

Explanation

First I create an anonymous orderof function which tells me the order (the number after e) of the input value. So

>> dt = 9.765625e-05;
>> orderof(dt)
ans =
    -5

Next we manipulate the number to convert it to a 4 digit integer, this is the effect of adding 3 in

>> floor(dt*(10^(abs(orderof(dt))+3)))
ans =
    9756

finally before printing the value we need to figure out the new exponent with

>> orderof(x)-3
ans =
    -8

and printing will give us

>> sprintf('%.0fe%03d', floor(dt*(10^(abs(orderof(dt))+3))), orderof(dt)-3)
ans =
    9765e-08

Upvotes: 1

Adriaan
Adriaan

Reputation: 18177

figStr = sprintf('NS2d_dt%1.4e',dt)
figStr =
NS2d_dt9.7656e-05

specify the number (1.4 here) as NumbersBeforeDecimal (dot) NumbersAfterDecimal.

Regarding your request:

A = num2str(dt);     %// convert to string
B = A([1 3 4 5]);    %// extract first four digits
C = A(end-2:end);    %// extract power
fspec = 'NS2d_dt%de%d'; %// format spec
sprintf(fspec ,str2num(B),str2num(C)-3)
NS2d_dt9765e-8

Upvotes: 0

il_raffa
il_raffa

Reputation: 5190

Reading your question,

The punctuation mark dot presents me with problems, some systems mistake the format of the file.

it seems to me that your actual problem is that when you build the file name using, for example

figStr = sprintf('NS2d_dt%.2e',dt);

you get

figStr = NS2d_dt9.77e-05

and, then, when you use that string as filename, the . is intepreted as the extension and the .pdf is not attached, so in Explorer you can not open the file double-clicking on it.

Considering that changing the representation of the number dt from 9.765e-05 to 9765e-08 seems quite wierd, you can try the following approach:

  • use the print function to save your figure in .pdf
  • add .pdf in the format specifier

This should allows you the either have the right file extension and the right format for the dt value.

peaks
figStr = sprintf('NS2d_dt_%.2e.pdf',dt);

print(gcf,'-dpdf', figStr )

Hope this helps.

Upvotes: 0

Related Questions