Numbers: the full set of types, and real literals that take their type

The numeric types table lists bigint, int128, uint128, float and decimal.
A real literal without a suffix is a double, float or decimal as the
context says. A boolean prints as #t.

🤖 Generated with [ECA](https://eca.dev)

Co-Authored-By: eca-agent <git@eca.dev>
This commit is contained in:
Linus Björnstam 2026-10-21 13:05:45 +02:00
parent bd71102c19
commit 481538a1cb
2 changed files with 22 additions and 13 deletions

View file

@ -2315,22 +2315,25 @@ Nothing about @code{list-sort} knows about cards. It asks for @code{(Ord %a)}, a
@subsubsection{The types} @subsubsection{The types}
There are eight numeric types, each a .NET primitive: The numeric types are the .NET ones:
@read-table{ @read-table{
| Type | Range | Type | Range | | Type | Range | Type | Range |
|----------------+------------------------------+----------------+------------------------| |----------------+------------------------------+----------------+---------------------------|
| @code{byte} | 0 … 255 | @code{uint} | 0 … 2^32−1 | | @code{byte} | 0 … 255 | @code{uint} | 0 … 2^32−1 |
| @code{short} | −32 768 … 32 767 | @code{long} | −2^63 … 2^63−1 | | @code{short} | −32 768 … 32 767 | @code{long} | −2^63 … 2^63−1 |
| @code{ushort} | 0 … 65 535 | @code{ulong} | 0 … 2^64−1 | | @code{ushort} | 0 … 65 535 | @code{ulong} | 0 … 2^64−1 |
| @code{int} | about ±2.1 billion | @code{double} | 64-bit floating point | | @code{int} | about ±2.1 billion | @code{double} | 64-bit floating point |
| @code{bigint} | any integer | @code{float} | 32-bit floating point |
| @code{int128} | −2^127 … 2^127−1 | @code{decimal} | 28 digits, exact decimals |
| @code{uint128} | 0 … 2^128−1 | | |
} }
There is no @code{float} and no @code{decimal}. A @code{char} is not a number: it can be compared and converted, but not added. A @code{char} is not a number: it can be compared and converted, but not added.
@subsubsection{Writing numbers} @subsubsection{Writing numbers}
A number with a suffix is of that type. A decimal point or an exponent makes it a @code{double}: A number with a suffix is of that type. A decimal point or an exponent makes it a real number, which is a @code{double}, a @code{float} or a @code{decimal}, and never an integer:
@read-table{ @read-table{
| Written | Type | | Written | Type |
@ -2341,11 +2344,14 @@ A number with a suffix is of that type. A decimal point or an exponent makes it
| @code{21u} | @code{uint} | | @code{21u} | @code{uint} |
| @code{21L} | @code{long} | | @code{21L} | @code{long} |
| @code{21UL} | @code{ulong} | | @code{21UL} | @code{ulong} |
| @code{21d} @code{2.5} @code{1e3} | @code{double} | | @code{21d} @code{2.5d} | @code{double} |
| @code{21M} @code{2.5M} | @code{decimal} |
| @code{21I} | @code{bigint} |
| @code{2.5} @code{1e3} | a real type, as the context says |
| @code{0x2A} @code{0b101010} | 42, of whatever type the context says | | @code{0x2A} @code{0b101010} | 42, of whatever type the context says |
} }
A number without a suffix has no type of its own. It takes the type of wherever it is used, and is an @code{int} only when nothing says otherwise: A number without a suffix has no type of its own. It takes the type of wherever it is used, and is an @code{int}, or a @code{double} if it is real, only when nothing says otherwise:
@codeblock[#:lang "bjolang"]|{ @codeblock[#:lang "bjolang"]|{
(: doubled (-> ushort ushort)) (: doubled (-> ushort ushort))
@ -2355,9 +2361,12 @@ A number without a suffix has no type of its own. It takes the type of wherever
(let ((start 5)) (let ((start 5))
(+ start 3L)) ;; 8L: start was a long all along (+ start 3L)) ;; 8L: start was a long all along
(: tenth decimal)
(def tenth 0.1) ;; a decimal, so (+ tenth 0.2) is exactly 0.3
}| }|
A literal that does not fit the type it ends up with is a compile error. @code{(doubled 99999)} says that 99999 does not fit in a @code{ushort}. A literal that does not fit the type it ends up with is a compile error. @code{(doubled 99999)} says that 99999 does not fit in a @code{ushort}, and @code{(doubled 2.5)} that 2.5 has a fraction.
@subsubsection{Arithmetic} @subsubsection{Arithmetic}

View file

@ -1718,7 +1718,7 @@ Literal prefixes like @code{#map(...)} are reader-level hash macros. You can reg
(defun (main) (defun (main)
(println #card(Q hearts)) ;; Q♥ (println #card(Q hearts)) ;; Q♥
(println #card[10 spades]) ;; 10♠, either bracket works (println #card[10 spades]) ;; 10♠, either bracket works
(println (court? #card(K clubs))) ;; True (println (court? #card(K clubs))) ;; #t
(with-each-card (c [#card(A spades) #card(2 hearts)]) (with-each-card (c [#card(A spades) #card(2 hearts)])
(println #"a card: ${c}")) (println #"a card: ${c}"))
0) 0)