# Parsing Numbers
**Trivet** provides convenience methods to parse three kinds of numbers.
- Unsigned integers as `u128`
- Signed integers as `i128`
- Floating point numbers as `f64`
To parse a number, you can just use one of the number parsing methods available in `trivet::Parser`.
| `parse_i128() -> ParseResult<i128>` | Parse a signed integer. |
| `parse_i128_ws() -> ParseResult<i128>` | Parse a signed integer and then consume any trailing whitespace. |
| `parse_u128() -> ParseResult<u128>` | Parse an unsigned integer. |
| `parse_u128_ws() -> ParseResult<u128>` | Parse an unsigned integer and then consume any trailing whitespace. |
| `parse_f64() -> ParseResult<f64>` | Parse a floating point number. |
| `parse_f64_ws() -> ParseResult<f64>` | Parse a floating point number and then consume any trailing whitespace. |
All of these can fail for various reasons, so they return a `ParseResult`.
Here is a very short example that parses floating point numbers from the standard input and then writes them to the standard output.
```rust,ignore
{{#include ../../examples/book_numbers_float.rs}}
```
## Number Representation
Numbers can be represented in any of the following radices.
- Decimal
- Hexadecimal
- Octal
- Binary
Radices other than decimal are indicated by a prefix.
| `0b` | Binary |
| `0o` | Octal |
| none | Decimal |
| `0x` | Hexadecimal |
By default, underscores can be present in numbers. This can be disabled if not desired. The following are some examples of signed and unsigned integers.
- `0x1011_1010` = 186
- `0o272` = 186
- `-0xba` = -186
Floating point numbers can be given in different radices, too. For instance, the following are a few ways to write a floating point value equivalent[^float] to 1/2.
| Binary | `0b0.1`, `0b1e-1` |
| Octal | `0o0.4`, `0o4e-1` |
| Decimal | `0.5`, `5e-1` |
| Hexadecimal | `0x0.8`, `0x8p-1` |
Note in the last example above that `p` is used for exponents in hexadecimal to avoid ambiguity. You can use `p` for any base, but cannot use `e` for hexadecimal for obvious reasons.
The general form for floating point numbers is as follows.
```text
Digit+ '.' Digit* |
Digit* '.' Digit+ ) Exp?
```
## Configuring Number Parsing
Number parsing is performed by the struct `trivet::numbers::NumberParser`. A number parser is already installed in each instance of `trivet::Parser`, and you can obtain mutable access to it to configure it using `borrow_number_parser() -> &mut NumberParser`.
| `borrow_number_parser() -> &mut NumberParser` | Obtain a mutable reference to the internal number parser. |
You can enable and disable support for different radices and can even change the prefix indicator used to detect radices. Disabling radices you don't want to support can increase performance a bit since **Trivet** does not need to check for the related prefixes.
## A Note About Parsing Numbers
We've seen some examples of parsing numbers already, but this can be trickier than you might think. A naive signed integer parsing method might look as follows.
```rust,ignore
// Bad Example
let negative = parser.peek_and_consume('-');
let digits = parser.take_while(|ch| ch.is_ascii_digit());
let number = match result.parse::<i64>() {
Ok(number) => number,
Err(err) => return Err(trivet::errors::error(parser.loc(), err)),
};
if negative { -number } else { number }
```
This seems really good, but it breaks for the maximum negative value. Because the absolute value of the most negative `i64` is higher than the absolute value of the most positive `i64` value, we _can't_ parse the most negative value with this method. The implementation in **Trivet** handles this case correctly.