format floating points in matlab using fprintf function - matlab

Consider the following code:
A1 = [9.9, 9900];
A2 = [8.8, 7.7 ; ...
8800, 7700];
formatSpec = 'X is %4.2f meters or %8.3f mm\n';
fprintf(formatSpec, A1, A2)
X is 9.90 meters or 9900.000 mm
X is 8.80 meters or 8800.000 mm
X is 7.70 meters or 7700.000 mm
I would like to know what does 4.2f or 8.3f mean in this case? Does it means how many digit we should use after .?
For instance by looking on code, it seems for me difficult to understand what they mean, while .2 or .3 appears a bit clear, first digit 4 and 8 became difficult to interpret, if it is related to mantissa and exponent, then why do we need it there?
Please help me to clarify such things

The first number indicates the total number of character spaces (including the delimiting .) the number will take up when printed. The second - as you pointed out - represents the number of decimals.
For example, if you print 1.2 with 8.3f you get three empty spaces before the number:
1.200
12345678 characters total
If you were to use 5.2f your output would be.
1.20
12345 characters total
The second line was added by me to illustrate the total number of characters (including white space). It is not part of the original output
Edit
In your example, using 8.3f for 1.2 wouldn't make much sense. However, if you wanted to write lots of column data to a file that could easily be read by another program, this might be more useful (because the format could be known). E.g. Consider two columns %8.3f%8.3f (note how you do not need a space between the floating point number formatter). This could give you an output like this:
1.200 34.564
8503.000 101.008
... and so on so forth. Here, the leading blank space helps. It will fail when you have numbers above 9999.999 in this case.
Edit 2
In Matlab, if you specify a number of total characters that is less than the number of digits you have before the decimal point (or none at all), it will just print the entire number. E.g. using %2.3f will give you
1.200
with no leading white spaces. If you only cared about the decimals printed, you could also use %.3f which again results in
1.200

Related

Why did MATLAB delete my decimals?

Let's say I create some number A, of the order 10^4:
A = 81472.368639;
disp(A)
8.1472e+04
That wasn't what I wanted. Where are my decimals? There should be six decimals more. Checking the variable editor shows me this:
Again, I lost my decimals. How do I keep these for further calculations?
Scientific notation, or why you didn't lose any decimals
You didn't lose any decimals, this is just MATLAB's way of displaying large numbers. MATLAB rounds the display of numbers, both in the command window and in the variable editor, to one digit before the dot and four after that, using scientific notation. Scientific notation is the Xe+y notation, where X is some number, and y an integer. This means X times 10 to the power of y, which can be visualised as "shift the dot to the right for y places" (or to the left if y is negative).
Force MATLAB to show you all your decimals
Now that we know what MATLAB does, can we force it to show us our number? Of course, there're several options for that, the easiest is setting a longer format. The most used for displaying long numbers are format long and format longG, whose difference is apparent when we use them:
format long
A
A =
8.1472368639e+04
format longG
A
A =
81472.368639
format long displays all decimals (up to 16 total) using scientific notation, format longG tries to display numbers without scientific notation but with most available decimals, again: as many as there are or up to 16 digits, both before and after the dot, in total.
A more fancy solution is using disp(sprintf()) or fprintf if you want an exact number of decimals before the dot, after the dot, or both:
fprintf('A = %5.3f\n',A) % \n is just to force a line break
A = 81472.369
disp(sprintf('A = %5.2f\n',A))
A = 81472.37
Finally, remember the variable editor? How do we get that to show our variable completely? Simple: click on the cell containing the number:
So, in short: we didn't lose any decimals along the way, MATLAB still stores them internally, it just displays less decimals by default.
Other uses of format
format has another nice property in that you can set format compact, which gets rid of all the additional empty lines which MATLAB normally adds in the command window:
format compact
format long
A
A =
8.147236863931789e+04
format longG
A
A =
81472.3686393179
which in my opinion is very handy when you don't want to make your command window very big, but don't want to scroll a lot either.
format shortG and format longG are useful when your array has very different numbers in them:
b = 10.^(-3:3);
A.*b
ans =
1.0e+07 *
0.0000 0.0001 0.0008 0.0081 0.0815 0.8147 8.1472
format longG
A.*b
ans =
Columns 1 through 3
81.472368639 814.72368639 8147.2368639
Columns 4 through 6
81472.368639 814723.68639 8147236.8639
Column 7
81472368.639
format shortG
A.*b
ans =
81.472 814.72 8147.2 81472 8.1472e+05 8.1472e+06 8.1472e+07
i.e. they work like long and short on single numbers, but chooses the most convenient display format for each of the numbers.
There's a few more exotic options, like shortE, shortEng, hex etc, but those you can find well documented in The MathWork's own documentation on format.

printf number format for constant width lat/long in exiftool

Apparently I am misunderstanding the printf man page. (Or else it's a bug in exiftool 10.55 and 10.77)
I am trying to get GPS coordinates from image files with exiftool. I would like to make them the same width and without unnecessary spaces.
The format string I tried, and one of the results:
-coordFormat "%03d°%02d′%0d%02.5f″"
042°37′280.00000″ N, 002°05′510.00000″ W
(I don't need five decimal places—I just put that in temporarily to see whether any of the cameras wer being dishonest about the precision.) The three unnecessary spaces can't be helped; they are outside the format string’s control, but I did get rid of others that were in the default.  The leading zero for latitude isn't needed, but it is there because longitude uses the same format string.  One problem is the bogus zero inserted between floor(seconds) and its decimal point. The other problem is the false fractional part.  The default format for that file is 42 deg 37' 28.39" N, 2 deg 5' 51.96" W
Someone's "cheat sheet" said that my second digit should be the total width, including the decimal point, so I changed the seconds to "%08.5f" but all that did was add another bogus zero in front of the decimal point, e.g., 510.00000→5100.00000 (width of ten, not eight!).
A few years ago, I did something similar, and got the correct results.  But I didn't bother to save the script "for future reference."
(Several other SO answers agree with that "cheat sheet.")
It looks like the issue is with the seconds field, for which you have the format specifier %0d%02.5f. I'm not sure what you intended, but there can be only one % for each value to be rendered
If you're formatting longitude then you are dealing with values between -180 and 180. If you want five decimal points then the total width will be
One character for the sign + or -
Three characters for the integer part
One character for the decimal point .
Five fractional digits
giving a total field width of ten. Your full specifier will be %0+10.5f, giving output between «-180.00000» and «+180.00000»
You may use a space flag instead of the +, as in %0 10.5f, which will use a space instead of a + to indicate a positive number, rendering 180 as « 180.00000». The leading zero is there so that zeroes are use to fill the full ten character field with
When dealing with latitude, you will need a total width one character smaller. %0+9.5f will result in a range of «-90.00000» to «+90.00000». Of course you may use the same format specifier as for longitude, which will produce «-090.00000» to «+090.00000». This way the latitude and longitude seconds will have the same number of characters
The %0d is throwing you off. That part of the template is consuming the "51.0" seconds component of the coordinate, leaving nothing for the %02.5d part of the template.
printf "%0d", 51 ===> "51"
printf "%02.5f"; ===> "0.00000"
printf "%0d%02.5f", 51 ===> "510.00000"
So lose the %0d.
The 2 in %02.5f also doesn't do you any good. The number before the decimal place is the minimum length of the field, and the number after the decimal place is the number of decimal places to use. Since 5 decimal places will be printed, the output will be at least 7 characters, and the 2 value will be ignored.
First number is the width, second number is the number of decimal points so what you have currently (%2.5f) appears to be backwards. %5.2f would give you a number that occupies 5 characters and has 2 decimal places. For a number as big as 510, you probably want to make it %6.2f

Formatting a float to a certain length with Powershell

I am trying to round/ only print out floating numbers to a certain length no matter what the value is (I have a document that it needs to fit properly in). I am using powershell but I haven't found anything useful.
There can be a max of 6 digits if you include a decimal point.
Here is what i am looking for below.
17.12356 => 17.1236
189.12345 => 189.123
12345 => 12345.0
122909808 => 122909 ( I haven't though of a proper way to show this case, suggestions would be helpful)
The G format specifier will truncate your number to a specified number of significant digits, but without any forward zero padding of small numbers. The following code gives an example of the kind of thing you might get for various types of numbers and with 5 significant digits (6 chars wide allowing for the decimal point). Note that for very large or small numbers you get 'scientific' notation, which will obviously be wider than 6 chars. For these cases you would need to find the large numbers and move the 'E' at least 4 spaces to the left , but then you lose a lot of detail. Up to you what you want to sacrifice, really.
PS > #(12345.678,123.45678,12345678,12345,123.4, 0.00123456) |%{"{0:G6}" -f $_} | %{if ($_.Leng
th -le7) {$_} else {$_.Substring(0,7)} }
12345.7
123.457
1.23457
12345
123.4
0.00123

Integer view format in Matlab

I have a matlab code that its output will print as an input text file for other program. But the numbers format is important in input file of my desired program it should start with 0. and then the number. For example, I want to format the output of Matlab program from the 3.00E+03 to 0.30E+04.
Can anyone between you experts kindly help me?
Many tanx
Please check the reference for fprintf. You can find it in the format specifier:
http://www.mathworks.nl/help/matlab/ref/fprintf.html
Probably the format you desire is not available in MATLAB so you can create your own!
First use log 10 to obtain the power (assuming):
Assuming a number X.
% Number to convert
X = 3867;
% Number of decimals after comma
n = 2;
% Calculation of the power to print
power = floor(log10(X))+1;
% Calculation of the decimals (correctly rounded)
decimals = round(X/10^(power-n));
% The format of fprintf. 0. is static, %d represents the printed decimals, %+0.3d represents the power. + denoting the sign, 0. denoting padding with zeros, 3 denoting the number of characters printed (if less characters in the power padded with zeros).
fprintf('0.%dE%+0.3d',decimals,power)
Kind regards,
Ernst Jan

Random Number in Octave

I need to generate a random number that is between .0000001 and 1, I have been using rand(1) but this only gives me 4 decimal points, is there any other way to do this generation?
Thanks!
From the Octave docs:
By default, Octave displays 5 significant digits in a human readable form (option ‘short’ paired with ‘loose’ format for matrices).
So it's probably an issue with the way you're printing the value rather than the value itself.
That same page shows the other output formats in addition to short, the one you may want to look in to is long, giving 15 significant digits.
And there is also the output_precision which can be set as per here:
old_val = output_precision (7)
disp (whatever)
old_val = output_precision (old_val)
Set the output_precision to 7 and it should be ok :)
Setting the output precision won't help though because the number can still be less than .0000001 in theory but you will only be displaying the first 7 digits. The simplest way is:
req=0;
while (req<.0000001)
req=rand(1);
end
It is possible that this could get you stuck in a loop but it will produce the right number. To display all the decimals you can also use the following command:
format long
This will show you 15 decimal places. To switch back go:
formay short