string->number(3scm)
π string->number(3scm) π
okay bestie, so this is page string->number(3scm) from the Scheme Programmer's Manual, and it's literally the glow-up guide for turning a lil string into a whole number. buckle up π
β¨ NAME β¨
string->number β convert a string to a number. that's it, that's the whole vibe π
π LIBRARY π
ok so depending on which flavor of Scheme you're living in, you import one of these:
(import (rnrs)) ;R6RS
(import (rnrs base)) ;R6RS
(import (scheme r5rs)) ;R7RS
(import (scheme base)) ;R7RS
pick your fighter, they all slay π«Ά
πΈ SYNOPSIS πΈ
(string->number string)
(string->number string radix)
two forms, one iconic procedure π
π« DESCRIPTION π«
so basically it returns a number object with maximally precise representation expressed by the given string. fancy way of saying: it reads the string, gives you the most precise number it can. periodt β¨
radix has to be an exact integer object, and it has to be one of 2, 8, 10, or 16. literally only those four, no negotiating π
ββοΈ
if you do pass radix, it's the default radix β but heads up, it may be overridden by an explicit radix prefix written right there in the string itself, like "#o177". sneaky but valid π
if you don't pass radix? the default radix is 10. classic.
now the important part, bestie: if string is not a syntactically valid notation for a number, or it would result in a number that the implementation cannot represent, then string->number returns #f. and no cap β an error is never signaled due to the content of string. it just politely hands you #f and minds its business π
π§ IMPLEMENTATION NOTES π§
Chez Scheme
the string->number procedure in the (chezscheme) library accepts a radix between 2 and 36. yeah, it's built different. lowkey flexing on the R6RS kids π
π RETURN VALUES π
returns a single value which is a number object or #f. one value. that's the whole return party π
π EXAMPLES π
the basics, and they ate:
(string->number "100") => 100
(string->number "100" 16) => 256
(string->number "1e2") => 100.0
and now the R6RS ones β so here's the tea: an implementation may return #f instead of infinities or nans if they are not supported. and importantly, 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
see how "0/0" is out here getting #f while the infinities are thriving? yeah. that's the whole point of that note π
π RATIONALE π
why does this exist? because it gives you access to the same number parser that is used in read(3scm) β or at least a functionally equivalent parser. consistency queen π
R7RS explains it like this, and honestly it's giving main character energy:
The rules used by a particular implementation forstring->numbermust also be applied toreadand 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#fwhenstringhas an explicit radix prefix has been withdrawn.
so yeah β that old permission? withdrawn. gone. it's not coming back π«‘
π¦ COMPATIBILITY π¦
you can look at this procedure two ways and get two whole different readings, ngl.
way one: if you see it as just "a door into the implementation's number parser," then it essentially works the same everywhere. universal vibe β¨
way two: if you look at which inputs give which results, then there can be large differences. like, big big. π¬
R6RS implementations are basically the same, except they may lack support for infinities and nans. R7RS implementations have much more leeway, and here's the official rundown:
The domain ofstring->numbermay be restricted by implementations in the following ways. If all numbers supported by an implementation are real, thenstring->numberis permitted to return#fwheneverstringuses the polar or rectangular notations for complex numbers. If all numbers are integers, thenstring->numbermay return#fwhenever the fractional notation is used. If all numbers are exact, thenstring->numbermay return#fwhenever an exponent marker or explicit exactness prefix is used. If all inexact numbers are integers, thenstring->numbermay return#fwhenever a decimal point is used.
so if your implementation is out here with a limited domain, it's allowed to hand you #f for all those fancy notations. not a bug, just the rules π
β ERRORS β
this procedure can raise exceptions with the following condition types:
&assertion(R6RS) β the wrong number of arguments was passed,stringwas not a string object, orradixwas passed but was not2,8,10, or16. all three of those will get you snapped at π’- 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. yeah. catastrophically. that's the actual word. no cap π
π SEE ALSO π
number->string(3scm)β the reverse queen, go say hi π«Ά
π STANDARDS π
R4RS, IEEE Scheme, R5RS, R6RS, R7RS
five for five, she's certified β¨
πΈ HISTORY πΈ
first appeared in R2RS, where it took three arguments: string, exactness, and radix. and the latter two arguments were symbols. wild times, truly ancestor behavior π
the modern two-argument variant first appeared in R4RS. glow-up complete π
π«Ά AUTHORS π«Ά
this page is part of the scheme-manpages project. it includes materials from the RnRS documents. more information can be found at https://github.com/schemedoc/manpages/ β go give them a follow, they're icons π
π BUGS π
ok bestie this is the serious one, pay attention:
Applications should not pass untrusted input to this procedure. It is easy to make it consume large amounts of memory and CPU time.
here's the receipts, literally the actual example from the page:
(time (bitwise-length (string->number "#e1e1000000")))
no collections
2.256397608s elapsed cpu time
2.256396107s elapsed real time
1392400 bytes allocated
3321929
so the number itself consumes several megabytes of memory and the conversion takes much longer to run than would be expected for such a short input. πππ
and because the universe has no mercy β adding a few more zeroes makes it an easy DoS. literally a few zeroes. that's all it takes. please guard your inputs, bestie, i'm begging π
that's the whole page, you're officially educated ππ this gem dropped in the scheme-manpages source, dated 2022-04-10, and was served to you fresh as string->number(3scm). go forth and parse responsibly β¨π¦πΈ
π¦ where this page comes from
- nixpkgs unstable: scheme-manpages 0-unstable-2024-02-11
- π the page's license: MIT
- Copyright (c) 2022 Gwen Weinholt
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms