3个不稳定版本
0.2.1 | 2021年3月29日 |
---|---|
0.2.0 | 2021年3月28日 |
0.1.0 | 2017年4月15日 |
在 算法 中排名 88
每月下载量 229,703
用于 1,057 个crate(10个直接使用)
21KB
414 行
hexf
为Rust 1.43或更高版本提供十六进制浮点数支持。(对于更早的版本,请尝试0.1.0
)
use hexf::hexf64;
assert_eq!(hexf64!("0x1.999999999999ap-4"), 0.1f64);
字面量显式指定类型,应与以下模式匹配:SIGN "0x" INTEGRAL "." FRACTIONAL "p" EXPSIGN EXPDIGITS
,其中
-
所有拉丁字母均不区分大小写匹配;
-
SIGN
和EXPSIGN
可以为+
、-
或空; -
INTEGRAL
和FRACTIONAL
是一个或多个十六进制数字,可选地由或以一个下划线(_
)分隔(但不能以它开始); -
至少有一个
INTEGRAL
或FRACTIONAL
应存在(允许1.0
或.0
或1.
,不允许1
); -
EXPDIGITS
是十进制数字,可选地由或以一个下划线(_
)分隔或开始或结束。
放置无效字面量是编译时错误。
// hexf32! failed: invalid hexadecimal float literal
let invalid = hexf32!("42");
放置无法在目标类型中精确表示的字面量也是编译时错误。
// hexf32! failed: cannot exactly represent float in target type
let inexact = hexf32!("0x1.99999bp-4");
// hexf32! failed: cannot exactly represent float in target type
let inexact_subnormal = hexf32!("0x1.8p-149");
// hexf64! failed: cannot exactly represent float in target type
let overflow = hexf64!("0x1.0p1024");
// hexf64! failed: cannot exactly represent float in target type
let underflow = hexf64!("0x1.0p-1075");
该crate(以及独立的hexf-parse
crate)提供了parse_hexf32
和parse_hexf64
函数,允许解析失败(通过ParseHexfError
类型报告)。这些函数只有在第二个参数为true时才允许交错下划线;这是为了保持一致性,因为Rust允许在数字字面量中使用下划线,但在标准库中不允许("3_4".parse::<i32>()
是错误)。
它是如何工作的?
此crate高度依赖于最近的Rust编译器可以正确打印和读取浮点数。因此,此crate的实际实现是通过将解析后的十六进制浮点数打印回正确的十进制数字,然后由编译器拾取以生成精确的位模式。
等等,那么十六进制浮点数的意义在哪里?答案是,它们是ISO C99“发明”的,以避免实现陷阱。理想情况下,应该可以枚举足够的分数位数以获得正确舍入的位模式,但许多实现并没有(相当可以理解,因为实际上相当困难)。因此,标准已经做出了妥协:在符合标准的实现中,十进制浮点数应解析为非常接近但不是精确的舍入数值
尾数部分被解释为(十进制或十六进制)有理数;指数部分的数字序列被解释为十进制整数。[...] 对于十进制浮点常量,以及当FLT_RADIX不是2的幂时,十六进制浮点常量,结果是最接近的可表示值,或者是与最接近的可表示值相邻的较大或较小可表示值,以实现定义的方式选择。[...]
——ISO C99,第6.4.4.2节 浮点常量,第3段(强调部分)
确实,解析这种精度下的十进制浮点数相对更容易。十六进制浮点数由此而来,但Rust不必!十六进制浮点数仍然可以用于手动编写浮点位,或者用于从其他语言转换。此crate就是为了这些较少用例而存在的。
有关更多信息,请参阅rust-lang/rust#1433。
lib.rs
:
解析十六进制浮点字面量。为每种类型提供了两个函数parse_hexf32
和parse_hexf64
。
use hexf_parse::*;
assert_eq!(parse_hexf32("0x1.99999ap-4", false), Ok(0.1f32));
assert_eq!(parse_hexf64("0x1.999999999999ap-4", false), Ok(0.1f64));
如果想要允许下划线,可以设置一个额外的bool
参数为true。
use hexf_parse::*;
assert!(parse_hexf64("0x0.1_7p8", false).is_err());
assert_eq!(parse_hexf64("0x0.1_7p8", true), Ok(23.0f64));
错误通过不可见的ParseHexfError
类型报告。