5个版本
0.1.4 | 2022年2月11日 |
---|---|
0.1.3 | 2022年1月21日 |
0.1.2 | 2022年1月21日 |
0.1.1 | 2022年1月21日 |
0.1.0 | 2022年1月21日 |
#184 in 无标准库
在3个Crates中使用(通过midpoint)
10KB
原始数字类型提升
根据Rust参考,Rust中的原始数字类型如下
数字类型
整数类型
无符号整数类型包括
类型 | 最小值 | 最大值 |
---|---|---|
u8 |
0 | 28-1 |
u16 |
0 | 216-1 |
u32 |
0 | 232-1 |
u64 |
0 | 264-1 |
u128 |
0 | 2128-1 |
有符号的补码整数类型包括
类型 | 最小值 | 最大值 |
---|---|---|
i8 |
-(27) | 27-1 |
i16 |
-(215) | 215-1 |
i32 |
-(231) | 231-1 |
i64 |
-(263) | 263-1 |
i128 |
-(2127) | 2127-1 |
浮点类型
IEEE 754-2008的"binary32"和"binary64"浮点类型分别是 f32
和 f64
。
机器相关的整数类型
类型 usize
是一个与平台指针类型位数相同的无符号整数类型。它可以表示进程中的每个内存地址。
类型 isize
是一个与平台指针类型位数相同的有符号整数类型。对象和数组大小的理论上限是最大的 isize
值。这确保了可以使用 isize
来计算对象或数组的指针之间的差异,并可以访问对象内的每个字节以及对象末尾之后的一个字节。
usize
和 isize
至少是16位宽。
注意:许多Rust代码可能假设指针、
usize
和isize
要么是32位,要么是64位。因此,16位指针支持有限,可能需要库的显式支持和认可。
为什么需要这个特性
所有原始数值类型,包括机器相关类型,都具有已知的大小,可以通过core::mem::size_of<T>()
来获取。大小越大,该类型能表示的可能值的数量就越多。作为集合的整数区间在许多运算下都不是闭合的,特别是加法和乘法。由于u8
表示整数区间[0..28-1],因此对于此类型也是如此。类似地,对于u16
、u32
等也是如此。同样,具有代数结构避免不精确性(即不同于浮点数的代数结构)的浮点数能表示的值的集合在许多运算下也不是闭合的。
解决此问题的一种方法是通过使用类型提升。类型提升允许使用表示原始类型超集的类型。对于每个原始数值类型(除了u128
、i128
和f64
),都有一个规范的类型提升。对于u8
,规范类型提升是u16
,对于i16
,规范类型提升是i32
,依此类推。
有符号整数
类型 | 大小 | 规范类型提升 | 提升大小 |
---|---|---|---|
i8 |
1字节 | i16 |
2字节 |
i16 |
2字节 | i32 |
4字节 |
i32 |
4字节 | i64 |
8字节 |
i64 |
8字节 | i128 |
16字节 |
i128 |
16字节 | 未定义 | 未定义 |
无符号整数
类型 | 大小 | 规范类型提升 | 提升大小 |
---|---|---|---|
u8 |
1字节 | u16 |
2字节 |
u16 |
2字节 | u32 |
4字节 |
u32 |
4字节 | u64 |
8字节 |
u64 |
8字节 | u128 |
16字节 |
u128 |
16字节 | 未定义 | 未定义 |
浮点数
类型 | 大小 | 规范类型提升 | 提升大小 |
---|---|---|---|
f32 |
4字节 | f64 |
8字节 |
f64 |
8字节 | 未定义 | 未定义 |
理论上,可以再进一步定义u256
,但这将不再是原始类型,并且对该类型的简单操作(如加法)甚至没有相应的CPU指令。
注意严格来说,u128
和i128
在当前架构上的支持不佳,是否合理使用PrimitivePromotionExt
扩展特质的实现可能值得商榷。然而,如果您想使用这些实现,您需要primitive_promotion
crate,因为u64
和i64
实现了PrimitivePromotionExt
特质。
示例
您会注意到PrimitivePromotionExt
的类型名称相当长。为了使其更短,建议将导入的特质重命名为PP
。因为它的使用意味着要配合完全限定语法,这种简写是必不可少的。
use primitive_promotion::PrimitivePromotionExt as PP;
fn midpoint(a: &u8, b: &u8) -> u8 {
// <u8 as TraitName>:: is an example of fully qualified syntax
let a = *a as <u8 as PP>::PrimitivePromotion;
let b = *b as <u8 as PP>::PrimitivePromotion;
((a+b)/2) as u8
}
fn main() {
let a: u8 = u8::MAX;
let b: u8 = u8::MAX;
assert_eq!(midpoint(&a,&b), u8::MAX);
}
许可证
许可协议为Apache License, Version 2.0或MIT license,您可自由选择。除非您明确声明,否则您提交给本crate的任何贡献,按照Apache-2.0许可协议定义,将以上述方式双重许可,无任何附加条款或条件。