1 个不稳定版本
0.1.0 | 2020年4月20日 |
---|
#115 在 值格式化
6,399 每月下载量
在 14 个crates中(8个直接)使用
58KB
905 行
format_num
动态将数字格式化为人类可读形式。
你遇到过Rust无法以你期望的方式表示数字的情况吗?
for i in 1..=10 {
println!("{}", 0.1 * i as f64);
}
你会得到这个
0.1
0.2
0.30000000000000004
0.4
0.5
0.6000000000000001
0.7000000000000001
0.8
0.9
1
这实际上不是Rust的问题,而是浮点数在二进制中的表示方式。
但是,舍入误差并不是定制数字格式的唯一原因。数字表应该格式化一致以便比较;上面的1.0比1.0更好。大数字可能需要分组数字(例如42,000)或以科学或公制符号(4.2e+4,42k)表示。报告的数值结果应四舍五入到有效数字(4021变为4000)等。
解析器基于Python 3的格式指定器迷你语言 (PEP3101),并进行了一些小的实现细节修改。
格式指定器的通用形式是
[[fill]align][sign][symbol][0][width][,][.precision][type]
填充字符可以是任何字符。填充字符的存在是通过其后的对齐字符来表示的,它必须是以下之一
>
- 强制字段在可用空间内右对齐。
<
- 强制字段在可用空间内左对齐。
^
- 强制字段在可用空间内居中对齐。
=
- 类似于 >
,但可以在任何填充的左侧放置任何符号和符号。
符号可以是
-
- 零或正数没有符号,负数有一个负号(默认行为)。
+
- 零或正数有一个加号,负数有一个减号。
(空格)- 零或正数,负数则带减号。
符号可以是
#
选项会导致使用“交替形式”进行转换。对于不同类型,交替形式的定义不同。对于整数,当使用二进制(b
)、八进制(o
或O
)或十六进制(x
或X
)输出时,此选项会在输出值前添加相应的“0b”、“0o”、“0O”或“0x”前缀。对于浮点数,交替形式会导致转换结果总是包含小数点字符,即使后面没有数字。
零(0)选项启用零填充;这会隐式地将填充设置为0并对齐设置为=。
宽度定义最小字段宽度;如果没有指定,则宽度将由内容决定。
逗号(,)选项启用使用分组分隔符,例如千位分隔符。
根据类型,精度要么表示小数点后的数字位数(类型f
和%
),要么表示有效数字的位数(类型e
和s
)。如果未指定精度,则默认为所有类型的6位。对于整数格式(类型b
、o
、d
、x
和X
),精度将被忽略。
可用的类型值包括
e
- 指数表示法。
f
- 固定点表示法。
s
- 带有SI前缀的十进制表示法,四舍五入到有效数字。
%
- 乘以100,然后使用带有百分号的十进制表示法。
b
- 二进制表示法,四舍五入到整数。
o
- 八进制表示法,四舍五入到整数。
d
- 十进制表示法,四舍五入到整数。
x
- 十六进制表示法,使用小写字母,四舍五入到整数。
X
- 十六进制表示法,使用大写字母,四舍五入到整数。
示例
use format_num::{NumberFormat, format_num};
fn main() {
let num = NumberFormat::new();
let format_spec = "+14d";
assert_eq!(num.format(".1f", 0.06), "0.1");
assert_eq!(num.format("#.0f", 10.1), "10."); // float alternate form (always show a decimal point)
assert_eq!(num.format("#b", 3), "0b11");
assert_eq!(num.format("b", 3), "11");
assert_eq!(num.format(format_spec, 2_147_483_647), " +2147483647");
// Or, you can use a macro for simplicity
assert_eq!(format_num!("#X", 48879), "0xBEEF");
assert_eq!(format_num!(".2s", 42e6), "42M");
assert_eq!(format_num!(".^20d", 12), ".........12........."); // dot filled and centered
assert_eq!(format_num!("+10.0f", 255), " +255");
assert_eq!(format_num!(".0%", 0.123), "12%");
assert_eq!(format_num!("+016,.2s", 42e12), "+000,000,000,042T"); // grouped zero-padded with a mandatory sign, SI-prefixed with 2 significant digits
}
注意
当前的一个限制是,要格式化的数字应该实现Into<f64>
,对于大于u64::MAX的数字,可能会丢失一些精度。
路线图
更多类型的实现:g
(通用格式)、n
(数字)、c
(字符)。
此外,还计划添加对区域设置和货币格式的支持。
许可证
format_num根据您的选择,受Apache License,版本2.0或MIT许可证的许可。
依赖项
~2.2–3MB
~54K SLoC