基本数据类型
固定宽度的数值类型
-
固定宽度的数值类型可能会溢出或丢失精度,但它们足以满足大多数应用程序的需求,并且比任意精度整数和精确理数等表示法快数千倍。`
-
Rust中的数值类型的名称都遵循着一种统一的模式,也就是以“位”数表示它们的宽度,以前缀表明它们的用法
大小(位) 无符号整数 有符号整数 浮点数 8 u8 i8 16 u16 i16 32 u32 i32 f32 64 u64 i64 f64 128 u128 i128 机器字 usize isize - usize 和 isize 是根据平台架构自动调整大小的整数类型
-
Rust 的无符号整型会使用它们的完整范围来表示正值和 0
类型 范围 u8 0 到 2^8-1 (0 到 255) u16 0 到 2^16-1 (0 到 65,535) u32 0 到 2^32-1 (0 到 4,294,967,295) u64 0 到 2^64-1 (0 到 18,446,744,073,709,551,615 或 1844 京) u128 0 到 2^128-1 (0 到 到大约 3.4×10^38) usize 0 到 2^32-1 或 2^64-1 -
Rust的有符号整型会使用二进制补码表示,使用与相应的无符号类型相同的位模式来覆盖正值和负值的范围
类型 范围 i8 -2^7 到 2^7-1 (-128 到 127) i16 -2^15 到 2^15-1 (-32,768 到 32,767) i32 -2^31 到 2^31-1 (-2,147,483,648 到 2,147,483,647) i64 -2^63 到 2^63-1 (-9,223,370,036,854,775,808 到 9,223,370,036,854,775,807) i128 -2^127 到 2^127-1 (大约-1.7x10^38 到 到大约 1.7×10^38) isize -2^31 到 2^32-1 或 -2^63 到 2^63-1 -
为了让长数值更易读,可以在数字之间任意插入下划线。例如,可以将 u32 的最大值写为 4_294_967_295。下划线的具体位置无关紧要,因此也可以将十六进制数或二进制数按 4 位数字而非 3 位数字进行分组(如0xffff_ffff),或分隔开数字的类型后缀(如127_u8)
-
Rust数值计算时如果是debug模式,溢出会报错,但是如果是release模式会回绕:它生成的值等于“数学意义上的正确结果”
-
如果这种默认行为不是你想要的,则整型提供的某些方法可以让你准确地阐明自己期望的行为。
- 检查运算会返回结果的 Option 值:如果数学意义上正确的结果可以表示为该类型的值,那么就为 Some(v),否则为None。
// 10与20之和可以表示为u8 assert_eq!(10_u8.checked_add(20), Some(30)); // 很遗憾,100与200之和不能表示为u8 assert_eq!(100_u8.checked_add(200), None); // 做加法。如果溢出,则会出现panic let sum = x.checked_add(y).unwrap(); // 奇怪的是,在某种特殊情况下,带符号的除法也会溢出。 // 带符号的n位类型可以表示-2n-1,但不足以表示2 n-1 assert_eq!((-128_i8).checked_div(-1), None);
-
回绕运算会返回与“数学意义上正确的结果”对“值类型范围”取模的值相等的值。
// 第一个结果可以表示为u16,第二个则不能,所以会得到250000 对2^16的模 assert_eq!(100_u16.wrapping_mul(200), 20000); assert_eq!(500_u16.wrapping_mul(500), 53392); // 对有符号类型的运算可能会回绕为负值 assert_eq!(500_i16.wrapping_mul(500), -12144); // 在移位运算中,移位距离会在值的大小范围内回绕, // 所以在16位类型中移动17位就相当于移动了1位 assert_eq!(5_i16.wrapping_shl(17), 10);
-
饱和运算会返回最接近“数学意义上正确结果”的可表达值。换句话说,结果“紧贴着”该类型可表达的最大值和最小值。
assert_eq!(32760_i16.saturating_add(10), 32767); assert_eq!((-32760_i16).saturating_sub(10), -32768);
-
不存在饱和除法 、饱和求余法 或饱和位移法
-
溢出运算会返回一个元组 (result, overflowed),其中result 是函数的回绕版本所返回的内容,而 overflowed 是一个布尔值,指示是否发生过溢出。
assert_eq!(255_u8.overflowing_sub(2), (253, false)); assert_eq!(255_u8.overflowing_add(2), (1, true));
-
overflowing_shl 和 overflowing_shr 稍微偏离了这种模式:只有当移位距离与类型本身的位宽一样大或比其更大时,它们才会为 overflowed 返回 true。实际应用的移位数是所请求的移位数对类型位宽取模的结果。
// 移动17位对`u16`来说太大了,而17对16取模就是1 assert_eq!(5_u16.overflowing_shl(17), (10, true))
-
前缀 checked_、wrapping_、saturating_ 或 overflowing_后面可以跟着的运算名称
运算 名称后缀 例子 加法 add 100_i8.checked_add(27) == Some(127) 减法 sub 10_u8.checked_sub(11) == None 乘法 mul 128_u8.saturating_mul(3) == 255 除法 div 64_u16.wrapping_div(8) == 8 求余 rem (-32768_i16).wrapping_rem(-1) == 0 取负 neg (-128_i8).checked_neg() == None 绝对值 abs (-32768_i16).wrapping_abs() == -32768 求幂 pow 3_u8.checked_pow(4) == Some(81) 按位左移 shl 10_u32.wrapping_shl(34) == 40 按位右移 shr 40_u64.wrapping_shr(66) == 10 -
IEEE单精度浮点类型和IEEE双精度浮点类型
类型 精度 范围 f32 IEEE单精度(至少6位小数) 大约 -3.4 x 10^38 至 +3.4 x 10^38 f64 IEEE双精度(至少15位小数) 大约 -1.8 x 10^308 至 +1.8 x 10^308 - 浮点数的类型推断(没有在字面量明确类型后缀)Rust会检查上下文查看值的使用方式。如果最终发现两种浮点类型都合适,就会默认选择f64。
- 为了便于类型推断,Rust会将整型字面量和浮点字面量视为不同的大类;它永远不会把整型字面量推断为浮点类型,反之亦然。
字面量 类型 数学值 -1.5625 自动推断 -(1^9/16) 2. 自动推断 2 0.25 自动推断 1/4 1e4 自动推断 10000 40f32 f32 40 9.109_383_56e-31f64 f64 大约9.10938356 x 10^-31
-
评论区