Listing 2.4, run: base 2, 8 and 16¶
Rust in Action, run › Chapter 2 › §2.3.2 · the book's file: ch2/ch2-non-base2.rs ↗
Level: 101 · a companion to Rust in Action, chapter 2
One line: On rustc 1.98.0, listing 2.4's four output lines match the book byte for byte, and so does the positional arithmetic after it. The section leaves out three traps: 036 without the o is thirty-six, 0x1f32 is the integer 7986 rather than a float, and from_str_radix does not accept the prefix you write in source.
What the listing prints¶
base 10: 3 30 300
base 2: 11 11110 100101100
base 8: 3 36 454
base 16: 3 1e 12c
Seven claims, run¶
Verified output of non_base2.rs — regenerated by tools/run_examples.py, never hand-typed.
1. 3 30 300
0x12C == 0x12c: true; their types: i32 i32 i32
2. 2*1 + 1*1 = 3, 8*3 + 1*6 = 30, 256*1 + 16*2 + 1*12 = 300
3. 036 = 36, 0o36 = 30
4. 0x1f32 = 7986, an i32; 0x1_u32 = 1
5. 100101100 0b100101100 | 454 0o454 | 12c 12C 0x12c 0x012c
6. Ok(300) | Err(ParseIntError { kind: InvalidDigit })
7. -3_i8: 11111101 fd
0b,0oand0xchange how the number is written, not its type. All three literals arei32, the fallback, like any unsuffixed integer. Hex digits may be either case; the prefix letter is always lowercase. → The prefix- The book's arithmetic is right. Each digit is multiplied by a power of the base: 300 = 1·16² + 2·16¹ + 12·16⁰, where the hex digit
Cstands for 12. → Why hexadecimal - A leading zero on its own is not octal.
036is thirty-six. In C, the same literal is octal and means thirty, and rustc 1.98.0 prints no warning about it. → A leading zero on its own means nothing - A hex literal swallows a suffix made of hex digits. In
0x1f32, the lettersf,3and2are hex digits, so the whole thing is one integer, 7986. It is not a float, and Rust has no hex float literals anyway (transcript below). Integer suffixes start withioru, which are not hex digits, so0x1u32and0x1_u32mean what they look like. → The suffix is the type - In
println!, a letter picks the base,#adds the prefix, and the width includes it. The book shows{:b},{:o}and{:x}.{:X}prints uppercase digits,{:#x}prints0x12c, and{:#06x}pads to six characters, prefix included:0x012c. → Rust's four spellings, The format mini-language - Parsing a number back takes the base as an argument; the prefix is not accepted.
i32::from_str_radix("12C", 16)isOk(300), and the same call on"0x12C"isInvalidDigit. →from_str_radixtakes a radix, not a prefix - A negative number prints its two's-complement bits.
{:b}of-3_i8is11111101, with no minus sign, and{:x}isfd. → Hex of a signed integer is two's complement
What the compiler refuses¶
A digit that is too big for the base is caught while the literal is being read:
error: invalid digit for a base 2 literal
--> binary_digit_two.rs:2:20
|
2 | let three = 0b12;
| ^
error: invalid digit for a base 8 literal
--> octal_digit_eight.rs:2:19
|
2 | let eight = 0o8;
| ^
And the only base a float literal can be written in is decimal:
error: hexadecimal float literal is not supported
--> hex_float.rs:2:13
|
2 | let x = 0x1.8;
| ^^^^^
Concepts, keywords, topics¶
| In the listing | Keyword or concept | Lesson here | Normative source |
|---|---|---|---|
0b11, 0o36, 0x12C |
numeric literal prefix, radix | Writing a number down · Why hexadecimal | Integer literals ↗ |
{:b}, {:o}, {:x} |
formatting traits Binary, Octal, LowerHex |
The format mini-language | Formatting traits ↗ |
the digits of 0x12C |
positional notation, nibble | Why hexadecimal · Bit flags | — |
reading 12c back |
from_str_radix |
Why hexadecimal · Parsing a string | i32::from_str_radix ↗ |
| a negative value in base 2 | two's complement | Meet the byte | Integer types ↗ |
The glossary defines hexadecimal, nibble, radix, numeric literal prefix, from_str_radix and two's complement.
See also¶
- Previous: Listing 2.3, run: integers and floats · next: Tables 2.1 and 2.2, run: numeric types and their bits
- Rust in Action, run — the chapter's listings, and a concept index across them
- Printing bytes — when the numbers are a
&[u8]rather than one integer
Po polsku¶
Listing 2.4 wypisuje na rustc 1.98.0 co do bajtu to, co pokazuje książka, a rachunek pozycyjny po nim się zgadza (0x12C = 1·16² + 2·16 + 12 = 300). Przedrostek (0b, 0o, 0x) zmienia tylko zapis liczby, nie typ — wszystkie trzy literały są i32.
Trzy pułapki, których książka nie wspomina. Samo zero na początku nic nie znaczy: 036 to trzydzieści sześć, choć w C to liczba ósemkowa równa 30. Literał szesnastkowy „połyka” przyrostek złożony z cyfr szesnastkowych: 0x1f32 to liczba całkowita 7986, a nie f32 (literałów zmiennoprzecinkowych w zapisie szesnastkowym Rust w ogóle nie ma). I from_str_radix przyjmuje podstawę jako argument, a przedrostka nie rozumie: "0x12C" to błąd InvalidDigit. Liczba ujemna wypisana binarnie pokazuje kod uzupełnień do dwóch (two's complement): -3_i8 to 11111101.
Szukaj po polsku: system dwójkowy ósemkowy szesnastkowy · kod uzupełnień do dwóch · rust from_str_radix 0x prefix · rust {:#x} format