]> git.proxmox.com Git - rustc.git/blame - src/doc/rust-by-example/src/types/cast.md
New upstream version 1.62.1+dfsg1
[rustc.git] / src / doc / rust-by-example / src / types / cast.md
CommitLineData
2c00a5a8
XL
1# Casting
2
3Rust provides no implicit type conversion (coercion) between primitive types.
4But, explicit type conversion (casting) can be performed using the `as` keyword.
5
6Rules for converting between integral types follow C conventions generally,
7except in cases where C has undefined behavior. The behavior of all casts
8between integral types is well defined in Rust.
9
10```rust,editable,ignore,mdbook-runnable
11// Suppress all warnings from casts which overflow.
12#![allow(overflowing_literals)]
13
14fn main() {
15 let decimal = 65.4321_f32;
16
17 // Error! No implicit conversion
18 let integer: u8 = decimal;
19 // FIXME ^ Comment out this line
20
21 // Explicit conversion
22 let integer = decimal as u8;
23 let character = integer as char;
24
cdc7bbd5
XL
25 // Error! There are limitations in conversion rules.
26 // A float cannot be directly converted to a char.
ba9703b0
XL
27 let character = decimal as char;
28 // FIXME ^ Comment out this line
29
2c00a5a8
XL
30 println!("Casting: {} -> {} -> {}", decimal, integer, character);
31
32 // when casting any value to an unsigned type, T,
ba9703b0 33 // T::MAX + 1 is added or subtracted until the value
2c00a5a8
XL
34 // fits into the new type
35
36 // 1000 already fits in a u16
37 println!("1000 as a u16 is: {}", 1000 as u16);
38
39 // 1000 - 256 - 256 - 256 = 232
40 // Under the hood, the first 8 least significant bits (LSB) are kept,
41 // while the rest towards the most significant bit (MSB) get truncated.
42 println!("1000 as a u8 is : {}", 1000 as u8);
43 // -1 + 256 = 255
44 println!(" -1 as a u8 is : {}", (-1i8) as u8);
45
46 // For positive numbers, this is the same as the modulus
47 println!("1000 mod 256 is : {}", 1000 % 256);
48
49 // When casting to a signed type, the (bitwise) result is the same as
50 // first casting to the corresponding unsigned type. If the most significant
51 // bit of that value is 1, then the value is negative.
52
53 // Unless it already fits, of course.
54 println!(" 128 as a i16 is: {}", 128 as i16);
04454e1e
FG
55
56 // 128 as u8 -> -128, whose two's complement in eight bits is:
2c00a5a8
XL
57 println!(" 128 as a i8 is : {}", 128 as i8);
58
59 // repeating the example above
60 // 1000 as u8 -> 232
61 println!("1000 as a u8 is : {}", 1000 as u8);
62 // and the two's complement of 232 is -24
63 println!(" 232 as a i8 is : {}", 232 as i8);
29967ef6 64
cdc7bbd5
XL
65 // Since Rust 1.45, the `as` keyword performs a *saturating cast*
66 // when casting from float to int. If the floating point value exceeds
67 // the upper bound or is less than the lower bound, the returned value
68 // will be equal to the bound crossed.
29967ef6
XL
69
70 // 300.0 is 255
71 println!("300.0 is {}", 300.0_f32 as u8);
72 // -100.0 as u8 is 0
73 println!("-100.0 as u8 is {}", -100.0_f32 as u8);
74 // nan as u8 is 0
75 println!("nan as u8 is {}", f32::NAN as u8);
76
cdc7bbd5
XL
77 // This behavior incurs a small runtime cost and can be avoided
78 // with unsafe methods, however the results might overflow and
79 // return **unsound values**. Use these methods wisely:
29967ef6
XL
80 unsafe {
81 // 300.0 is 44
82 println!("300.0 is {}", 300.0_f32.to_int_unchecked::<u8>());
83 // -100.0 as u8 is 156
84 println!("-100.0 as u8 is {}", (-100.0_f32).to_int_unchecked::<u8>());
85 // nan as u8 is 0
86 println!("nan as u8 is {}", f32::NAN.to_int_unchecked::<u8>());
87 }
2c00a5a8
XL
88}
89```