Fortran output of real number - fortran

have declared a variable:
real*4 FACTOR
and then FACTOR=2.25
I want to output 2.25
Tried F3.2
Any help?
WRITE (lu09,9315)FACTOR
9315 FORMAT (F4.2)

The Fortran format F3.2 would output numbers up to .99, but anything larger won't fit. If you mean you want 3 digits before the decimal, change it to F6.2.
The first format number is the total field width, including the decimal and fractional digits.
For 2.25 to appear, the format width must be at least 4: F4.2

The f0.2 format gives the desired output, as demonstrated below. It writes the number with two digits after the decimal point and as many digits before the decimal point as needed.
program xwrite
implicit none
real*4 :: factor = 2.25
write (*,"(f0.2)") factor
end program xwrite
! output:
! 2.25

Related

Binary to Octal

How to write code that converters a input file of binary numbers into octal. I had to write a code that converts it to decimal which I did, but now I'm supposed to write a code that converts it to octal by grouping the binary numbers in groups of 3 and then calling the binary to decimal function.
For example 10100 would be grouped 10 | 100. So I'd call binary to decimal on 10 and 100 and get 2 for 10 and 4 for 100, then place the numbers together to get 24, which is 10100 decimal in octal.
However, I cannot figure out how to group the numbers. (The number is type string by the way). Any tips would help thanks.
Simply add leading zeroes to your string if its length is not divisble by three then group them and convert to octal.

Converting CHAR to NUM with varying decimal places

I am trying to convert a column stored from character to numeric. The problem is that this column has varying number of decimal places.
For example,
Data
1052969525
392282764.234
221018301.2
130010764.7894
82340150
183779233.4
I have determined that the likely maximum of decimal places is 4, the width required would be about 15. So I have attempted the following:
datanum = input(data, 15.4);
But this appears to put the decimal place in the wrong place, especially for those that have no decimal places. What is the most reasonable way to convert this column from char to numeric? This column is part of a database table uploaded by someone else so there's not much option to change that. Thanks.
You don't normally supply the decimal width in informats. For a normal number, you only supply the width, and SAS will figure out the decimal for you (based on the position of the decimal point).
datanum = input(data,15.);
The .d part of an informat is to allow for compatibility with (mostly) older systems that did not have decimals in the data, to save space. For example, if I'm reading in money amounts, and I only have 6 spaces:
123456
882348
100000
123400
I can read that in as an integer amount of cents - or I can do:
input cost 6.2;
That will then tell SAS to place the decimal before the last 2 characters.

Why multiplying 1.0 to 5 gave output 5 and not 5.0?

cout<<5*1.0<<endl;
cout<<(float)5<<endl;
In both cases I got 5 as an answer and not 5.0. Please help...
You need to specify the format and precision for floatingPoint output, such as:
std::cout << std::fixed << std::setprecision(1) << 5*1.0;
LIVE
From [The.C++.Programming.Language.Special.Edition] 21.4.3 FloatingPoint Output [io.out.float]:
Floatingpoint output is controlled by a format and a precision:
– The
general format lets the implementation choose a format that presents a
value in the style that best preserves the value in the space
available. The precision specifies the maximum number of digits. It
corresponds to printf()’s %g (§21.8).
– The scientific format presents
a value with one digit before a decimal point and an exponent. The
precision specifies the maximum number of digits after the decimal
point. It corresponds to printf()’s %e .
– The fixed format presents a
value as an integer part followed by a decimal point and a fractional
part. The precision specifies the maximum number of digits after the
decimal point. It corresponds to printf()’s %f .

Reading and counting (double precision) real numbers from file with non-advancing I/O: what edit descriptor to use?

I am trying to read a list of real numbers from an external file into an array. I do not know how many records fields, separated by spaces, there are per record in a file, and I was therefore planning to use non-advancing I/O to first count the number of records fields, then allocate a real array of sufficient size, and to finally read the file into that same array.
Here is an example input file (where the edit descriptor should be f3.1 for every record field, i.e. a float 3 characters wide with one decimal, and counting the dot; although if I read Metcalf et al. correctly, the decimal is ignored):
1.0 2.0 3.0 4.0 5.0
And a MWE of my program looks like this
program testread
use iso_fortran_env
implicit none
character(len=255) :: filename
filename = 'read.dat'
print *, count_entries(filename)
contains
integer function count_entries(coefficient_file) result(n)
character(len=*), intent(in) :: coefficient_file
!real, dimension(:), allocatable :: coefficients
integer :: fileunit, stat
real :: temp
n=0
open(newunit=fileunit, file=coefficient_file, iostat=stat)
do
read(fileunit,'(f3.1)',advance='no',iostat=stat) temp
if (stat == iostat_end) then
exit
else
n = n + 1
end if
print *, stat, temp
end do
close(fileunit)
! What should happen in the future...
!allocate(coefficients(n))
!read(fileunit,*,iostat=stat) coefficients
end function count_entries
end program testread
If you save the sample input above as read.dat, compile the program with gfortran -o testread{,.f90} and execute it, you will get the following result:
0 1.00000000
0 2.00000000
0 0.300000012
0 0.00000000
0 4.00000000
0 5.00000000
-2 0.00000000
7
In other words, instead of counting 5 entries, it counts 7. And this is not surprising as it, for some reason, sees 7 numbers. But I wonder: why does it see 7 numbers? How can I extend my function to a) be able to also read larger reals and b) read reals of non-uniform width? For example, I would like to be able to read 1.01 1.003 2.1, etc.
It sees six numbers (the last one is an end of record condition) because your format specification specifies that three characters be read each time, but your data is spaced every four columns (three for the data, one for the separating blank).
If your input isn't fixed format (number of columns may vary), then read the whole record (line) into a character(:), allocatable variable and then manually chop that string up.
(Never use a format specification with a specified number of decimal places for input unless you know that your input will always suit that.)
You forgot to account for the spaces. Just use '(f3.1,1x)'.

Error when reading in float in Fortran

This should be quite simple, but I can't manage to read in a floating point number in Fortran. My program test.f looks like this:
PROGRAM TEST
open(UNIT=1,FILE='test.inp')
read(1,'(f3.0)')line
STOP
END
The input file test.inp simply contains a single float: 1.2
Now the compiling of my testfile goes fine, but when I run it I get an error:
At line 4 of file test.f (unit = 1, file = 'test.inp')
Fortran runtime error: Expected REAL for item 1 in formatted transfer, got INTEGER
(f3.0)
^
I've tried different modifications of the code and also googling for the error message, but with no result. Any help would be greatly appreciated!
Regards,
Frank
Your variable line is implicitly defined as integer. This doesn't work with thef edit descriptor. If you want to read an integer use i edit descriptor (i3 for example). Otherwise declare line as real to math the "f" descriptor.
Note beside: the .0 is not a problem, because if Fortran gets a number with decimal point the .0 part in the descriptor is ignored. It is only used when an number without a decimal is entered and then it uses the number behind the decimal point in the desciptor to add a decimal point into the right place. For with F8.5, 123456789 is read as 123.45678. More ont this here http://software.intel.com/sites/products/documentation/hpc/compilerpro/en-us/fortran/lin/compiler_f/lref_for/source_files/pghredf.htm .
In your read statement
read(1,'(f3.0)')line
the f3.0 tells tour program to read 3 digits with 0 digits after the decimal (this is what the n.m syntax means). So I presume that the program is just reading 1 from the file (not 1.2), which is an integer. Try replacing that line with something like
read(1,'(f3.1)')line
although, if the number in your file is likely to change and be larger than 9.9 or have more than one decimal place you should increase the field width to something larger than 3.
See the documentation of the read intrinsic and for data edit descriptors for more information on reading and writing in Fortran.
Edit: the format specifier, the second argument in quotes in your read statment, has the form fw.d, where f indicates that the data to read is a floating point number, w is the width of the field including all blanks and decimal points and d specifies the number of digits to the right of the decimal point.
I would suggest reading/writing list formatted data, unless you have a very strong reason to do otherwise. assuming that you're reading in from a file with just a single float or integer in a single line, like this
123.45
11
42
then this should do the reading
real*8 :: x,y,z
open(1,file=filename)
read(1,*)x
read(1,*)y
read(1,*)z
close(1)