How to fprintf of the array of floating-point numbers
Show older comments
I have an array of the floating-point numbers, let say
A = [ 1 2.2 3.33; 44 55.5 6.666];
The number of row/colums as well as the number of digits before and after the decimal point are vary.
I need to find the "format" %X.Yf, to properly fprintf this array:
fprintf(%X.Yf, A).
It is alright to print the array uniformly: all data have the same number of digits after the decimal point:
A =
1.000 2.200 3.330
44.000 55.500 6.666
I can find the maximum number of digits across array's data:
tmp1 = arrayfun(@num2str,A,'UniformOutput', false);
tmp2 = cellfun((@numel),tmp1);
max_length = max(tmp2(:));
max_length defines X+Y in the "format", but I need to find the Y.
Do I over-complicate the implementation?
Any help, please?
Thank you,
Lev
Accepted Answer
More Answers (2)
Image Analyst
on 26 Mar 2018
Will this work for you?
A = [ 1 2.2 3.33; 44 55.5 6.666]
for row = 1 : size(A, 1)
fprintf('%7.3f ', A(row, :));
fprintf('\n');
end
You'll see
1.000 2.200 3.330
44.000 55.500 6.666
2 Comments
Lev Vitkin
on 26 Mar 2018
Image Analyst
on 26 Mar 2018
It doesn't vary. It always uses the full mantissa length. See Walter's example where you might think that 3.33 has only two decimal places, but it really has many more than that if you print them all out.
If you want to find where you have a certain number of zeros in a row, like 3 or something, and then chop off the number starting at the first zeros, then you'll have to convert the number to a string and look for zeros, and print the string. For example:
str = sprintf('%.999g', 3.33) % 3.3300000000000000710542735760100185871124267578125
threeZeros = strfind(str, '000');
if ~isempty(threeZeros)
str = str(1:threeZeros-1)
end
fprintf('%s\n', str);
Walter Roberson
on 26 Mar 2018
>> fprintf('%.999g\n', 3.33)
3.3300000000000000710542735760100185871124267578125
that is 49 digits after the decimal place.
All of the entries with value between 2 and 4 will have the same number of digits after the decimal place, except the entries that happen to involve powers of 2 denominators in the fractions, such as 3.3125 (3 + 5/16) as happens for the 44 and 55.5 entries. For entries with value between 1 and 2, add one decimal place (i.e, 50 after the decimal point); for each power of 2 above that subtract 1 decimal place. You can use log2() to calculate the grouping. Basically, floor(log2(value)) + 50 is the number of decimal places after the decimal point, except for the cases that happen to involve M/2^N for some integer M and N.
2 Comments
Lev Vitkin
on 26 Mar 2018
@Lev Vitkin: the code you wrote is limited to 3 decimal places, so what is the point in that? Your code does not resolve your original question "I need to find the "format" %X.Yf... I need to find the Y." You just fixed Y==3, so if you are happy with that then what is the point of the question?
Your code is not very robust, and could be simplified, e.g.:
ceil(log10(max(1,abs(A)*(1+eps))))
better replaced with
1+fix(log10(max(1,abs(A))))
Note also that your code does not calculate Y (of your original question) anyway, because your concept for calculating lFrac is flawed. Try it with intermediate zeros and you will see that it will not work:
>> A = [1.001,22.002,333.003]
>> tmp = 1000*rem(A,1)2.00000 3.00000
>> tmp = ceil(log10(max(1,abs(tmp)*(1+eps))))
>> lFract = max(tmp(:))
lFract = 1
Do those numbers require one decimal digit, or three? Note that my answer correctly identifies that these require three decimal digits:
fmt = '%7.3f %7.3f %7.3f\n'
and prints this:
1.001 22.002 333.003
If you want code that actually adjusts to the precision of the numbers then see my answer.
Categories
Find more on Matrices and Arrays in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!