Skip to content

Commit 8c7461d

Browse files
authored
Merge pull request #743 from jalvesz/master
Proposal for a reference string to number conversion facility in stdlib
2 parents 9582167 + 3b50f6a commit 8c7461d

10 files changed

+884
-1
lines changed

ci/fpm-deployment.sh

+8-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ destdir="${DESTDIR:-stdlib-fpm}"
99
fypp="${FYPP:-$(which fypp)}"
1010

1111
# Arguments for the fypp preprocessor
12-
fyflags="${FYFLAGS:--DMAXRANK=4}"
12+
maxrank=4
13+
fyflags="${FYFLAGS:--DMAXRANK=$maxrank}"
1314

1415
# Number of parallel jobs for preprocessing
1516
if [ $(uname) = "Darwin" ]; then
@@ -44,6 +45,12 @@ mkdir -p "$destdir/src" "$destdir/test" "$destdir/example"
4445
find src -maxdepth 1 -iname "*.fypp" \
4546
| cut -f1 -d. | xargs -P "$njob" -I{} "$fypp" "{}.fypp" "$destdir/{}.f90" $fyflags
4647

48+
find test -name "test_*.fypp" -exec cp {} "$destdir/test/" \;
49+
fyflags="${fyflags} -I src"
50+
find $destdir/test -maxdepth 1 -iname "*.fypp" \
51+
| cut -f1 -d. | xargs -P "$njob" -I{} "$fypp" "{}.fypp" "{}.f90" $fyflags
52+
find $destdir/test -name "test_*.fypp" -exec rm {} \;
53+
4754
# Collect stdlib source files
4855
find src -maxdepth 1 -iname "*.f90" -exec cp {} "$destdir/src/" \;
4956
find test -name "test_*.f90" -exec cp {} "$destdir/test/" \;

doc/specs/stdlib_str2num.md

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
---
2+
title: str2num
3+
---
4+
5+
# The `stdlib_str2num` module
6+
7+
This module proposes a function-style interface for string-to-number conversion. It also profits from Fortran's interfaces to implement precision-dependant algorithms to maximize runtime efficiency.
8+
9+
[TOC]
10+
11+
## `to_num` - conversion of strings to numbers
12+
13+
### Status
14+
15+
Experimental
16+
17+
### Description
18+
19+
Convert a string or an array of strings to numerical types.
20+
21+
### Syntax
22+
23+
`number = [[stdlib_str2num(module):to_num(interface)]](string, mold)`
24+
25+
### Arguments
26+
27+
`string`: argument has `intent(in)` and is of type `character(*)`.
28+
29+
`mold`: argument has `intent(in)` and is of numerical type (that is of `integer` or of `real`). **Note**: The type of the `mold` argument defines the type of the result.
30+
31+
### Return value
32+
33+
Return a scalar of numerical type (i.e., `integer`, or `real`).
34+
35+
### Example
36+
37+
```fortran
38+
{!example/strings/example_string_to_number.f90!}
39+
```
40+
41+
## `to_num_from_stream` - conversion of a stream of values in a string to numbers
42+
43+
### Status
44+
45+
Experimental
46+
47+
### Description
48+
49+
Convert a stream of values in a string to an array of values.
50+
51+
### Syntax
52+
53+
`number = [[stdlib_str2num(module):to_num_from_stream(interface)]](string, mold)`
54+
55+
### Arguments
56+
57+
`string`: argument has `intent(in)` and is of type `character(:), pointer`.
58+
59+
`mold`: argument has `intent(in)` and is of numerical type (currently of `integer` or `real`). **Note**: The type of the `mold` argument defines the type of the result.
60+
61+
### Return value
62+
63+
Return a scalar of numerical type (i.e., `integer` or `real`).
64+
65+
### Example
66+
67+
```fortran
68+
{!example/strings/example_stream_of_strings_to_numbers.f90!}
69+
```
70+
71+
## Note
72+
The accuracy of the conversion is implementation dependent; it is recommended that implementers guarantee precision down to the last 3 bits.
73+
74+
**The current implementation has been tested to provide for** :
75+
76+
`sp` : exact match
77+
78+
`dp` : precision up-to epsilon(0.0_dp)
79+
80+
`qp` : precision around 200*epsilon(0.0_qp)
81+
82+
Where precision refers to the relative difference between `to_num` and `read`. On the other hand, `to_num` provides speed-ups ranging from 4x to >10x compared to the intrinsic `read`.

example/strings/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ ADD_EXAMPLE(starts_with)
1010
ADD_EXAMPLE(strip)
1111
ADD_EXAMPLE(to_string)
1212
ADD_EXAMPLE(zfill)
13+
ADD_EXAMPLE(string_to_number)
14+
ADD_EXAMPLE(stream_of_strings_to_numbers)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
program example_stream_of_strings_to_numbers
2+
use stdlib_kinds, only: dp
3+
use stdlib_str2num, only: to_num_from_stream
4+
character(:), allocatable, target :: chain
5+
character(len=:), pointer :: cptr
6+
real(dp), allocatable :: r(:), p(:)
7+
integer :: i
8+
9+
chain = " 1.234 1.E1 1e0 0.1234E0 12.21e+001 -34.5E1"
10+
allocate( r(6), p(6) )
11+
!> Example for streamline conversion using `to_num_from_stream`
12+
cptr => chain
13+
do i =1, 6
14+
r(i) = to_num_from_stream( cptr , r(i) ) !> the pointer is shifted within the function
15+
end do
16+
read(chain,*) p
17+
print *, "Reading with to_num_from_stream"
18+
print *, r
19+
print *, "Reading with formatted read"
20+
print *, p
21+
22+
end program example_stream_of_strings_to_numbers
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
program example_string_to_number
2+
use stdlib_kinds, only: dp
3+
use stdlib_str2num, only: to_num
4+
implicit none
5+
character(:), allocatable :: txt
6+
real(dp) :: x
7+
8+
txt = ' 8.8541878128e−12 '
9+
x = to_num( txt , x )
10+
end program example_string_to_number

src/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ set(fppFiles
5555
stdlib_math_is_close.fypp
5656
stdlib_math_all_close.fypp
5757
stdlib_math_diff.fypp
58+
stdlib_str2num.fypp
5859
stdlib_string_type.fypp
5960
stdlib_string_type_constructor.fypp
6061
stdlib_strings_to_string.fypp

0 commit comments

Comments
 (0)