Appearance
4. Numbers
The prices are text. Before computing with them report must know that they are numbers, and convert them.
Is it a number?
f90
prices(1) = '3000.00'
prices(2) = '4900.50'
prices(3) = '2500'
do p = 1, size(prices)
print '(A,3(1X,L1))', prices(p)//':', prices(p)%is_number(), prices(p)%is_real(), prices(p)%is_integer()
enddo
cell = 'n/a'
print '(A,1X,L1)', cell//':', cell%is_number()is_number is true for an integer or a real; is_integer and is_real tell them apart: a real has a decimal point or an exponent, 2500 is an integer and not a real.
From a string to a number
f90
highest = 0._R8P
do p = 1, size(prices)
price = prices(p)%to_number(kind=1._R8P) ! the kind of the result is the kind of the argument
highest = max(highest, price)
enddo
print '(A,F0.2)', 'highest price: ', highestto_number returns the number in the string. Its argument is not a value to convert: it only selects the kind of the result, here a real(R8P). The kinds are the portable ones of PENF, exported by stringifor: I1P, I2P, I4P, I8P, R4P, R8P. A cast to a real kind accepts an integer string too.
WARNING
to_number does not report an error: on something that is not a number it gives 0 (integer kinds) or NaN (real kinds). Check with is_number (or is_integer) first, or use read_number.
With an error status
f90
cell = 'n/a'
call cell%read_number(price, iostat=iostat, iomsg=iomsg) ! the failure is reported
if (iostat /= 0) print '(A)', cell//': '//trim(iomsg)
call prices(2)%read_number(price, iostat=iostat)
if (iostat == 0) print '(A,F0.2)', prices(2)//': ', priceread_number is a subroutine that does what to_number does and reports a failure as a read statement: iostat is 0 on success and positive otherwise, iomsg says what went wrong. The kind of the result is the one of the variable passed.
From a number to a string
f90
total = sum(prices%to_number(kind=1._R8P)) ! a number assigned to a string
print '(A)', 'total: '//total
total = 3_I4P
print '(A)', 'cars: '//total
total = 2001
print '(A)', 'year 2001 in hexadecimal: '//total%hex()A number of any kind is assigned to a string like a character. to_number is elemental, like most methods: applied to the array of prices it gives the array of numbers, that sum adds. hex gives the hexadecimal representation of the integer in the string.
Running it
$ report
3000.00: T T F
4900.50: T T F
2500: T F T
n/a: F
highest price: 4900.50
n/a: the string is not a number
4900.50: 4900.50
total: +0.10400500000000000E+005
cars: +3
year 2001 in hexadecimal: 7d1An integer keeps its sign, a real is written with all the significant digits of its kind: a string holds the number exactly as it is. When you want a layout, print the number with a format, as report does for the highest price.
The whole program:
f90
program report
!< Tutorial, chapter 4: numbers.
use stringifor
implicit none
type(string) :: prices(3), cell, total
real(R8P) :: price, highest
integer :: p, iostat
character(99) :: iomsg
prices(1) = '3000.00'
prices(2) = '4900.50'
prices(3) = '2500'
do p = 1, size(prices)
print '(A,3(1X,L1))', prices(p)//':', prices(p)%is_number(), prices(p)%is_real(), prices(p)%is_integer()
enddo
cell = 'n/a'
print '(A,1X,L1)', cell//':', cell%is_number()
highest = 0._R8P
do p = 1, size(prices)
price = prices(p)%to_number(kind=1._R8P) ! the kind of the result is the kind of the argument
highest = max(highest, price)
enddo
print '(A,F0.2)', 'highest price: ', highest
cell = 'n/a'
call cell%read_number(price, iostat=iostat, iomsg=iomsg) ! the failure is reported
if (iostat /= 0) print '(A)', cell//': '//trim(iomsg)
call prices(2)%read_number(price, iostat=iostat)
if (iostat == 0) print '(A,F0.2)', prices(2)//': ', price
total = sum(prices%to_number(kind=1._R8P)) ! a number assigned to a string
print '(A)', 'total: '//total
total = 3_I4P
print '(A)', 'cars: '//total
total = 2001
print '(A)', 'year 2001 in hexadecimal: '//total%hex()
endprogram reportWhat you learned
is_number, is_integer, is_real; to_number(kind=...) and read_number with an error status; numbers assigned to strings; hex. Reference: Numbers.
Next: 5. Files and paths.