string->number(3scm) Scheme Programmer's Manual string->number(3scm)

string->number - convert a string to a number

(import (rnrs))                     ;R6RS
(import (rnrs base))                ;R6RS
(import (scheme r5rs))              ;R7RS
(import (scheme base))              ;R7RS

(string->number string)
(string->number string radix)

Returns a number object with maximally precise representation expressed by the given string.

Radix must be an exact integer object, either 2, 8, 10, or 16. If supplied, radix is a default radix that may be overridden by an explicit radix prefix in string (e.g., "#o177"). If radix is not supplied, then the default radix is 10.

If string is not a syntactically valid notation for a number, or would result in a number that the implementation cannot represent, then string->number returns #f. An error is never signaled due to the content of string.

Chez Scheme
The string->number procedure in the (chezscheme) library accepts a radix between 2 and 36.

Returns a single value which is a number object or #f.

(string->number "100")     =>  100
(string->number "100" 16)  =>  256
(string->number "1e2")     =>  100.0

In the following examples from R6RS an implementation may return #f instead of infinities or nans if they are not supported. It does not, like it otherwise would, raise the conditions from make-no-infinities-violation(3scm) or make-no-nans-violation(3scm).

(string->number "0/0")     =>  #f
(string->number "+inf.0")  =>  +inf.0
(string->number "-inf.0")  =>  -inf.0
(string->number "+nan.0")  =>  +nan.0

This procedure provides access to the same number parser that is used in read(3scm), or at least a functionally equivalent parser. R7RS explains it like this:
The rules used by a particular implementation for string->number must also be applied to read and to the routine that reads programs, in order to maintain consistency between internal numeric processing, I/O, and the processing of programs. As a consequence, the R5RS permission to return #f when string has an explicit radix prefix has been withdrawn.

The compatibility of this procedure can be viewed in two different ways. If we look at this procedure as providing access to the number parser of the Scheme implementation then it essentially works the same everywhere. If we examine it in terms of which inputs give which results, then there can be large differences.

R6RS implementations are basically the same, except that they may lack support for infinities and nans. R7RS implementations have much more leeway:

The domain of string->number may be restricted by implementations in the following ways. If all numbers supported by an implementation are real, then string->number is permitted to return #f whenever string uses the polar or rectangular notations for complex numbers. If all numbers are integers, then string->number may return #f whenever the fractional notation is used. If all numbers are exact, then string->number may return #f whenever an exponent marker or explicit exactness prefix is used. If all inexact numbers are integers, then string->number may return #f whenever a decimal point is used.

This procedure can raise exceptions with the following condition types:
&assertion (R6RS)
The wrong number of arguments was passed, string was not a string object, or radix was passed but was not 2, 8, 10, or 16.
R7RS
The assertions described above are errors. Implementations may signal an error, extend the procedure's domain of definition to include such arguments, or fail catastrophically.

number->string(3scm)

R4RS, IEEE Scheme, R5RS, R6RS, R7RS

First appeared in R2RS, where it took three arguments: string, exactness, and radix. The latter two arguments were symbols. The modern two-argument variant first appeared in R4RS.

This page is part of the scheme-manpages project. It includes materials from the RnRS documents. More information can be found at https://weinholt.se/scheme/manpages/.

Applications should not pass untrusted input to this procedure. It is easy to make it consume large amounts of memory and CPU time:
(time (bitwise-length (string->number "#e1e1000000")))
    no collections
    2.256397608s elapsed cpu time
    2.256396107s elapsed real time
    1392400 bytes allocated
3321929

The number consumes several megabytes of memory and the conversion takes much longer to run than would be expected for such a short input. Adding a few more zeroes makes it an easy DoS.
2022-04-10