num2str for strict string lengths

15 views (last 30 days)
Hau Kit Yong
Hau Kit Yong on 24 Jan 2018
Commented: Hau Kit Yong on 24 Jan 2018
I have an array of numbers with varying orders of magnitude that I want to convert to strings that are of fixed lengths. The string lengths are strict as the FEM solver I am using (NASTRAN) uses character counts to split strings into separate fields. I have tried fiddling around with the format specifiers but I have not found one that is robust enough for my application.
An as example, if my desired string length is 8, and the input number is 123, I can just use sprintf('%8s', num2str(123)). However if the input number is -12345678, the same method will give me '-12345678' which is 9 characters long, whereas the desired string is '-1.2E+07'. Similarly, '123E6' gives me '1234000000' which is also longer than desired, whereas I would want '1.23E+09'.
I see the main issue is that the field width specifier does not recognise the negative sign and the exponent as part of the width. Is there a quick solution for this or would I need to set up a bunch of conditional statements to iteratively do num2str, check the resulting string length, and reduce the precision until it is of the desired length?
  1 Comment
Guillaume
Guillaume on 24 Jan 2018
Unless there's something on the FileExchance I'm afraid you're going to have to write it yourself as none of the num2str, sprintf format specifiers can do what you want nor is it something supported by Java or .Net (which you could have used directly in matlab).

Sign in to comment.

Answers (1)

Jan
Jan on 24 Jan 2018
The real problem is importing text files with a fixed width for numbers. This is such an idiotic format! Even if you get this managed to write such a file, '-1.2E+07' is a very poor representation of -12345678: Only 2 significant digits! Ugly.
The only real solution is to contact the authors of NASTRAN and ask for a better file import. Maybe there is one already, e.g. in binary format?
But you are asking for writing a text file with 8 characters per element. This does not work with sprintf directly, and num2str is only a wrapper for this function. Note that '-1.2E+07' could be written as '-1.234E7' to have 2 more valid digits, and '-12345E3' wins another digit.
function c = sprintf8(d)
c = sprintfc('%8g', d); % Undocumented sprintf into cell string
len = cellfun('length', C);
for k = find(len > 8)
mag = ceil(log10(abs(d(k))));
neg = d(k) < 0;
if ...
... yeah
end
end
end
Sorry, I thought about it for a while and it is not trivial. For considering negative and positive values as well as very high and low magnitudes, overflow and underflow, a lot of exceptions are required. An exhaustive test must confirm the quality of the output. This is more than I can write in the forum currently - I cannot run Matlab at the moment. Perhaps the posted fragment helps you to write it by your own. Or it convinces you to use a reliable format for the file.
  1 Comment
Hau Kit Yong
Hau Kit Yong on 24 Jan 2018
Thanks for taking the time to have a go at it! NASTRAN does accept other formats such as comma-separated fields but for my applications the text files might require some manual checking and modifying so having it in the fixed-width format makes it much more readable. NASTRAN can also take 16-character fixed-width fields which would help somewhat with the lack of precision of the 8-character format, but it would still be difficult to program a robust writer for it. The NASTRAN writer can obviously do it so I was just wondering if there's a simple way to implement it in MATLAB.

Sign in to comment.

Categories

Find more on Characters and Strings in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!