0x00 回顾
上一篇文章主要介绍了类型转换的一些概念和类型转换的3个原则,这篇文章将继续介绍类型转换的基本原则。
0x02 类型转换规则(Coercion Rule)
接上篇文章
4、浮点数转换为整数时,将会直接舍弃小数位,保留整数部分。另外还有下面3点要注意:
- 如果浮点数是
NAN,转为整数时将会返回0 - 如果当前的浮点数值大于所转换的整数类型的最大值,则将返回该整数类型的最大值
- 如果当前的浮点数值小于所转换的整数类型的最大值,则将返回该整数类型的最小值
示例代码:
// NAN 相当于 0.0 / 0.0 let a: f64 = f64::NAN; // 正无穷大 +∞ let b: f64 = f64::INFINITY; // 负无穷大 -∞ let c: f64 = f64::NEG_INFINITY; println!("NAN 转换为整数的值为 {}", a as i32); println!("+∞ 转换为整数的值为 {}", b as i32); println!("-∞ 转换为整数的值为 {}", c as i32); // 其它情况,直接舍弃小数,不会进行四舍五入 let d: f64 = 54.5; let e: f64 = 65.1; println!("浮点数 {} 转换为整数 {}", d, d as i32); println!("浮点数 {} 转换为整数 {}", e, e as i32);
代码执行结果:
NAN 转换为整数的值为 0 +∞ 转换为整数的值为 2147483647 -∞ 转换为整数的值为 -2147483648 浮点数 54.5 转换为整数 54 浮点数 65.1 转换为整数 65
5、整数转换为浮点数时,可能会发生数据浮动。
- 如果发生数据浮动,将遵循
roundTiesToEven模式。(数据round到到相邻最近的浮点数据上。如果两个浮点数据都一样近,则round到最后一位是偶数的浮点数据上) - 如果转换时发生溢出,则将会输出为无穷大(∞)
PS:在数值类型中,溢出仅发生在 u128 as f32的值大于或者等于f32::MAX + (0.5 ULP)时。
示例代码:
let a: i32 = 5; println!("{} 转为浮点数 {}", a, a as f64); // 溢出 let b: u128 = u128::MAX; println!("{} 转为浮点数 {}", b, b as f32);
代码执行结果:
5 转为浮点数 5 340282366920938463463374607431768211455 转为浮点数 inf
6、f32浮点数可以完美无损的转换为f64浮点数。
示例代码:
let a: f32 = 98.0; println!("f32浮点数 {} 转为 f64浮点数 {}", a, a as f64);
代码执行结果:
f32浮点数 98 转为 f64浮点数 98
7、f32浮点数转换f64浮点数时,可能会发生数据浮动。
- 如果发生数据浮动,将遵循
roundTiesToEven模式。(数据round到到相邻最近的浮点数据上。如果两个浮点数据都一样近,则round到最后一位是偶数的浮点数据上) - 如果转换时发生溢出,则将会输出为无穷大(∞)
示例代码:
// 数据浮动,注意精度 let a: f64 = 9045.213123; println!("f64浮点数 {} 转为 f32浮点数 {}", a, a as f32); // 溢出 let b: f64 = f64::MAX; println!("f64浮点数 {} 转为 f32浮点数 {}", b, b as f32);
代码执行结果:
f64浮点数 9045.213123 转为 f32浮点数 9045.213 f64浮点数 179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 转为 f32浮点数 inf
8、布尔型转为整数型。true转为整数的值是1,false转为整数的值是0。Rust不允许由整数转为布尔型
示例代码:
let a = false; let b = true; println!("{} 转为 整数为 {}", a, a as i32); println!("{} 转为 整数为 {}", b, b as i32);
代码执行结果:
false 转为 整数为 0 true 转为 整数为 1
9、u8类型转换为char类型
- 仅支持
u8型整数转为char类型。 char类型转为整数时,如果整数位数长度不够,则将发生截断,同上面说的第3点
示例代码:
// u8转为char let a: u8 = 97; println!("u8型整数 {} 转为 char 为{}", a, a as char); // char转整数 // 笑脸图标 let b: char = '\u{1F604}'; println!("char型 {} 转为i32的值为:{}, 其二进制为 {:032b}", b, b as i32, b as i32); println!("char型 {} 转为i16的值为:{}, 其二进制为 {:032b}", b, b as i16, b as i16); println!("char型 {} 转为i8的值为:{}, 其二进制为 {:032b}", b, b as i8, b as i8);
代码执行结果:
u8型整数 97 转为 char 为a char型 😄 转为i32的值为:128516, 其二进制为 00000000000000011111011000000100 char型 😄 转为i16的值为:-2556, 其二进制为 00000000000000001111011000000100 char型 😄 转为i8的值为:4, 其二进制为 00000000000000000000000000000100
0x03 小结
我花费一篇文章来讲了Rust中的数值间的类型转换,希望对大家有所帮助。当然as并不是仅可以应用于数值间的强制类型转换,还有如枚举,指针等等。其它类型的转换后续章节将会介绍。写到这里已经达到3000字了,由于篇幅问题,文章中并没有讲浮点数是如何转为二进制存储的,如果有感兴趣的同学可以查阅下资料。
0x04 参考资料
- 浮点数在线转换为二进制 IEEE-754 :https://babbage.cs.qc.cuny.edu/IEEE-754.old/Decimal.html
Rust 类型转换官方文档:https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions
Unicode所有区段 统一码编码范围 | Unicode符号库 :https://fuhaoku.net/blocks