# Numeric literals
## Table of contents
- [Overview](#overview)
- [Details](#details)
- [Integer literals](#integer-literals)
- [Real-number literals](#real-number-literals)
- [Digit separators](#digit-separators)
- [Divergence from other languages](#divergence-from-other-languages)
- [Alternatives considered](#alternatives-considered)
- [References](#references)
## Overview
The following syntaxes are supported:
- [Integer literals](#integer-literals)
- `12345` (decimal)
- `0x1FE` (hexadecimal)
- `0o755` (octal)
- `0b1010` (binary)
- [Real-number literals](#real-number-literals)
- `123.456` (digits on both sides of the `.`)
- `123.456e789` (optional `+` or `-` after the `e`)
- `0x1.2p123` (optional `+` or `-` after the `p`)
- [Digit separators](#digit-separators) (`_`)
Note that real-number literals always contain a `.` with digits on both sides,
and integer literals never contain a `.`.
Literals are case-sensitive. Unlike in C++, literals do not have a suffix to
indicate their type.
## Details
### Integer literals
Decimal integers are written as a non-zero decimal digit followed by zero or
more additional decimal digits, or as a single `0`.
Integers in other bases are written as a `0` followed by a base specifier
character, followed by a sequence of one or more digits in the corresponding
base. The available base specifiers and corresponding bases are:
| Base specifier | Base | Digits |
| -------------- | ---- | ------------------------ |
| `b` | 2 | `0` and `1` |
| `o` | 8 | `0` ... `7` |
| `x` | 16 | `0` ... `9`, `A` ... `F` |
The above table is case-sensitive. For example, `0b1`, `0o7`, and `0x1A` are
valid, and `0B1`, `0O7`, `0X1A`, and `0x1a` are invalid.
A zero at the start of a literal can never be followed by another digit: either
the literal is `0`, the `0` begins a base specifier, or the next character is a
decimal point (see below). The `0o` prefix is used for octal literals; a C-style
`0755` octal is invalid in Carbon.
### Real-number literals
Real numbers are written as a decimal or hexadecimal integer followed by a
period (`.`) followed by a sequence of one or more decimal or hexadecimal
digits, respectively. A digit is required on each side of the period. `0.` and
`.3` are both lexed as two separate tokens: `0.(Util.Abs)()` and `tuple.3` both
treat the period as member or element access, not as a radix point.
To support tuple indexing, a real number literal is never formed immediately
following a `.` token with no intervening whitespace. Instead, the result is an
integer literal.
A real number can be followed by an exponent character, an optional `+` or `-`
(defaulting to `+` if absent), and a character sequence matching the grammar of
a decimal integer with some value _N_. For a decimal real number, the exponent
character is `e`, and the effect is to multiply the given value by
10±_N_. For a hexadecimal real number, the exponent character
is `p`, and the effect is to multiply the given value by
2±_N_. The exponent suffix is optional for both decimal and
hexadecimal real numbers.
Note that a decimal integer followed by `e` is not a real-number literal. For
example, `3e10` is not a valid literal.
When a real-number literal is interpreted as a value of a real-number type, its
value is the representable real number closest to the value of the literal. In
the case of a tie, the nearest value whose mantissa is even is selected.
The decimal real number syntax allows for any decimal fraction to be expressed
-- that is, any number of the form _a_ x 10-_b_, where _a_ is an
integer and _b_ is a non-negative integer. Because the decimal fractions are
dense in the reals and the set of values of the real-number type is assumed to
be discrete, every value of the real-number type can be expressed as a real
number literal. However, for certain applications, directly expressing the
intended real-number representation may be more convenient than producing a
decimal equivalent that is known to convert to the intended value. Hexadecimal
real-number literals are provided in order to permit values of binary floating
or fixed point real-number types to be expressed directly.
### Digit separators
A digit separator (`_`) may occur between any two digits within a literal. For
example:
- Decimal integers: `1_23_456_7890`
- Hexadecimal integers: `0x7_F_FF_FFFF`
- Octal literals: `0o7_55`
- Binary literals: `0b1_000_101_11`
- Real-number literals: `2_147.48_3648e12_345` or `0x1_00CA.FE_F00Dp+2_4`
## Divergence from other languages
The design provides a syntax that is deliberately close to that used both by C++
and many other languages, so it should feel familiar to developers. However, it
selects a reasonably minimal subset of the syntaxes. This minimal approach
provides benefits directly in line with the goal that Carbon code should be
[easy to read, understand, and write](/docs/project/goals.md#code-that-is-easy-to-read-understand-and-write):
- Reduces unnecessary choices for programmers.
- Simplifies the syntax rules of the language.
- Improves consistency of written Carbon code.
That said, it still provides sufficient variations to address important use
cases for the goal of not leaving room for a lower level language:
- Hexadecimal, octal, and binary integer literals.
- Scientific notation floating point literals.
- Hexadecimal (scientific) floating point literals.
## Alternatives considered
- [Integer bases](/proposals/p0143.md#integer-bases)
- [Octal literals](/proposals/p0143.md#octal-literals)
- [Decimal literals](/proposals/p0143.md#decimal-literals)
- [Case sensitivity](/proposals/p0143.md#case-sensitivity)
- [Real number syntax](/proposals/p0143.md#real-number-syntax)
- [Disallow ties](/proposals/p0866.md)
- [Digit separator syntax](/proposals/p0143.md#digit-separator-syntax)
- [3-digit decimal groupings](/proposals/p1983.md#3-digit-decimal-groupings)
- [2-digit or 4-digit hexadecimal digit groupings](/proposals/p1983.md#2-digit-or-4-digit-hexadecimal-digit-groupings)
- [Disallow digit separators in fractions](/proposals/p1983.md#disallow-digit-separators-in-fractions)
- [No octal literals](/proposals/p6910.md#no-octal-literals)
## References
- Proposal
[#143: Numeric literals](https://github.com/carbon-language/carbon-lang/pull/143)
- Proposal
[#866: Allow ties in floating literals](https://github.com/carbon-language/carbon-lang/pull/866)
- Proposal
[#1983: Weaken digit separator placement rules](https://github.com/carbon-language/carbon-lang/pull/1983)
- Proposal
[#6910: Support octal literals](https://github.com/carbon-language/carbon-lang/pull/6910)