Reputation: 18484
I'm writing a function that requires floating-point values to be converted to strings to be passed into (closed) C code. String conversion is the slowest part of my code and the input arrays can be very large. sprintf
is fast and the g
conversion character results in compact a representation:
x = [-1.75 0 1 pi 2^57];
sprintf('%.17g ',x)
which returns
-1.75 0 1 3.1415926535897931 1.4411518807585587e+17
Like with sprintf
's C equivalent, insignificant zeros are not printed when the g
or G
conversion characters are specified. However, the C code I'm using requires that numeric values include the decimal point and trailing zero. Another option that retains the same precision is:
x = [-1.75 0 1 pi 2^57];
sprintf('%.17f ',x)
which returns
-1.75000000000000000 0.00000000000000000 1.00000000000000000 3.14159265358979312 144115188075855872.00000000000000000
But this leads to ballooning of the string array (the input vectors can be big and complex-valued).
How can I efficiently and compactly (speed and memory) print my numbers to strings while adding a trailing zero if needed and produce an output like this?
-1.75 0.0 1.0 3.1415926535897931 1.4411518807585587e+17
Ideally this could be done directly within the format string so that sprintf
can do the work. If that doesn't work, what other options are there and what's the fastest? regexprep
is far too slow so don't even think about it. If you like, you might use x = repmat([-1.75 0 1 pi 2^57],1e5,1);
as your test array for timing purposes.
Upvotes: 0
Views: 322
Reputation: 22509
First I define what format specs I want to use.
Then I determine which is appropriate and create the format spec string.
x = [-1.75 0 1 pi 2^57];
s = {'%.17g ', '%.1f'};
idx = (x-floor(x) < 0.1 & x < 10^9) + 1;
fspec = reshape(char(s(idx))', 1, []);
Gives me
>> sprintf(fspec, x)
ans =
-1.75 0.0 1.0 3.1415926535897931 1.4411518807585587e+17
Upvotes: 1