#primitive #extension #promotion

无std primitive_promotion

原始数字类型提升:u8提升为u16,i16提升为i32,f32提升为f64等

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

MIT/Apache

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"浮点类型分别是 f32f64

机器相关的整数类型

类型 usize 是一个与平台指针类型位数相同的无符号整数类型。它可以表示进程中的每个内存地址。

类型 isize 是一个与平台指针类型位数相同的有符号整数类型。对象和数组大小的理论上限是最大的 isize 值。这确保了可以使用 isize 来计算对象或数组的指针之间的差异,并可以访问对象内的每个字节以及对象末尾之后的一个字节。

usizeisize 至少是16位宽。

注意:许多Rust代码可能假设指针、usizeisize 要么是32位,要么是64位。因此,16位指针支持有限,可能需要库的显式支持和认可。

为什么需要这个特性

所有原始数值类型,包括机器相关类型,都具有已知的大小,可以通过core::mem::size_of<T>()来获取。大小越大,该类型能表示的可能值的数量就越多。作为集合的整数区间在许多运算下都不是闭合的,特别是加法和乘法。由于u8表示整数区间[0..28-1],因此对于此类型也是如此。类似地,对于u16u32等也是如此。同样,具有代数结构避免不精确性(即不同于浮点数的代数结构)的浮点数能表示的值的集合在许多运算下也不是闭合的。

解决此问题的一种方法是通过使用类型提升。类型提升允许使用表示原始类型超集的类型。对于每个原始数值类型(除了u128i128f64),都有一个规范的类型提升。对于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指令。

注意严格来说,u128i128在当前架构上的支持不佳,是否合理使用PrimitivePromotionExt扩展特质的实现可能值得商榷。然而,如果您想使用这些实现,您需要primitive_promotion crate,因为u64i64实现了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许可协议定义,将以上述方式双重许可,无任何附加条款或条件。

无运行时依赖