Appearance
Numbers
The kinds
use stringifor exports the portable kinds of PENF:
| Parameter | Type | Bytes |
|---|---|---|
I1P | integer | 1 |
I2P | integer | 2 |
I4P | integer | 4 |
I8P | integer | 8 |
R4P | real | 4 |
R8P | real | 8 |
R16P | real | 16 |
R16Pis supported (in the assignment and into_number) when the library is compiled with the-DPENF_R16Ppreprocessor flag.I2Pis not supported when the_NVFmacro is defined (NVIDIA Fortran compatibility).
Is it a number?
f90
program number_check
!< Is it a number?
use stringifor
implicit none
type(string) :: s(6)
integer :: i
s(1) = '42' ; s(2) = '-3.14' ; s(3) = '6.02e23' ; s(4) = '1.' ; s(5) = '12 apples' ; s(6) = '007'
print '(A)', 'string number integer real digit'
do i = 1, size(s)
print '(A,4(L1,6X))', s(i)%fill(width=12, right=.true., filling_char=' ')//'', &
s(i)%is_number(), s(i)%is_integer(), s(i)%is_real(), s(i)%is_digit()
enddo
endprogram number_check$ number_check
string number integer real digit
42 T T F T
-3.14 T F T F
6.02e23 T F T F
1. T F T F
12 apples F F F F
007 T T F T| Method | True if the string is |
|---|---|
is_integer([allow_spaces]) | an integer, with an optional sign |
is_real([allow_spaces]) | a real: digits with a decimal point or an exponent (or both); an integer is not a real |
is_number([allow_spaces]) | an integer or a real |
is_digit() | made of digits only |
Leading and trailing blanks are accepted, unless allow_spaces=.false..
From a string to a number
f90
program number_cast
!< From a string to a number.
use stringifor
implicit none
type(string) :: s
real(R8P) :: x
integer(I4P) :: n
s = '3.4e2'
if (s%is_number()) x = s%to_number(kind=1._R8P) ! the kind of the argument selects the result
print '(F0.1)', x
s = '42'
if (s%is_integer()) n = s%to_number(kind=1_I4P)
print '(I0)', n + 1
x = s%to_number(kind=1._R8P) ! an integer string is a valid real
print '(F0.1)', x
endprogram number_cast$ number_cast
340.0
43
42.0to_number(kind) returns the number in the string. The argument selects the kind of the result and nothing else: its value is ignored, pass any constant of the wanted kind (1_I4P, 1._R8P). A cast to a real kind accepts a real or an integer string, a cast to an integer kind an integer string.
A plain decimal number (a sign, at most 18 significant digits, a decimal point, an exponent) is converted without the read statement when the result is exact: any integer in the range of the kind, and a real whose digits and power of ten are exact in the kind (up to 15 digits and 1e22 for R8P), a single correctly rounded operation. Every other string goes through read: the result is the same, the plain numbers are about twenty times faster.
WARNING
On a string that does not hold a suitable number the result is 0 for an integer kind and a quiet NaN for a real kind: check with is_number or is_integer first to tell a parsed 0 from a failure, or use read_number.
With an error status
f90
program checked_cast
!< Numbers read from strings, with an error status.
use stringifor
implicit none
type(string) :: fields(3)
real(R8P) :: value
integer :: iostat
character(len=99) :: iomsg
integer :: f
fields(1) = '3.25'
fields(2) = 'n/a'
fields(3) = '1e3'
do f = 1, size(fields)
call fields(f)%read_number(value, iostat=iostat, iomsg=iomsg)
if (iostat == 0) then
print '(A,F8.2)', fields(f)//' -> ', value
else
print '(A)', fields(f)//' -> error: '//trim(iomsg)
endif
enddo
endprogram checked_cast$ checked_cast
3.25 -> 3.25
n/a -> error: the string is not a number
1e3 -> 1000.00read_number(number[, iostat][, iomsg]) is a subroutine: the kind is the one of number, and the failure is reported as by a read statement, iostat being 0 on success and positive otherwise, iomsg explaining it. On failure number gets the same value as to_number, 0 or NaN. It is elemental: on an array of strings, number and iostat are arrays.
From a number to a string
f90
program number_to_string
!< From a number to a string.
use stringifor
implicit none
type(string) :: s
s = 42
print '(A)', s//''
s = -127_I1P
print '(A)', s//''
s = 2.5_R4P
print '(A)', s//''
s = 1._R8P/3._R8P
print '(A)', s//''
s = 255
print '(A)', s%hex()//' '//s%hex(uppercase=.true.)
s = -1
print '(A)', s%hex(bits=16)//'' ! two's complement on 16 bits
endprogram number_to_string$ number_string
+42
-127
+0.250000000E+01
+0.33333333333333331E+000
ff FF
ffff- An integer is written with its sign; a real with its sign and all the significant digits of its kind, so the string holds the nearest representable value. For another layout, write the number with a format into a character.
hex([bits][, uppercase])returns the hexadecimal representation of the integer in the string, or a string not allocated if it is not an integer. A negative number is in two's complement onbitsbits (default 64); the number is truncated to its lowestbitsbits.