【问题标题】:generate float with leading zeroes and string with trailing space生成带有前导零的浮点数和带有尾随空格的字符串
【发布时间】:2023-01-09 00:44:24
【问题描述】:

我正在尝试打印出字符串“name”的固定长度为 20(尾随空格)的行。

然后我想生成一个包含 10 个整数和 8 个小数的浮点数(数量),问题是我不知道如何用前导零格式化数量/浮点数,使它们的长度相同,也出于某种原因,目前所有的小数都变成了零。

我想要的输出:

John Doe            D4356557654354645634564563.15343534
John Doe            C5674543545645634565456345.34535767
John Doe            C0000000000000000000000000.44786756
John Doe            D0000000000000000000865421.12576545

当前的输出是什么样的:

John Doe            12345678912345C390571360.00000000
John Doe            12345678912345D5000080896.00000000
John Doe            12345678912345C4320145.50000000
John Doe            12345678912345C1073856384.00000000

代码

use rand::Rng;
use pad::PadStr;

struct Report {
    name: String,
    account_number: i64,
    letter: char,
    amount: f32,
}

fn main() {

  let mut n = 1;
  let mut rng = rand::thread_rng();

  while n < 101 {
    let acc = Report {
        name: String::from("John Doe").pad_to_width(20),
        account_number: 12345678912345,
        letter: rng.gen_range('C'..='D'),
        amount: rng.gen_range(100.1..9999999999.9),
    };


    println!("{}{}{}{:.8}\n", acc.name, acc.account_number, acc.letter, acc.amount);
    n += 1;
  }

  }

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=e229dbd212a94cd9cc0be507568c48d5

(出于某种原因,“pad”在操场上不起作用)

【问题讨论】:

  • D4356557654354645634564563.144.85343534 应该是什么?它有多个点...
  • 请提供“预期输出”实际上与您的问题有什么关系。另外,请不要一次问多个问题。您目前正在问为什么字符串上的左填充不起作用,如何打印固定长度的浮点数以及为什么随机生成的浮点数是整数。
  • 对不起,这是一个错字,现在已经编辑并修复了它。
  • 为什么你的“预期输出”在与当前输出不同的位置有一个“D”或“C”?
  • 你是什​​么意思'然后我想生成一个浮点数'?特定分布?如果不是,为什么不直接生成两个整数并在中间加一个点呢?

标签: rust


【解决方案1】:

您看不到任何逗号后值的原因是 f32 没有足够的精度来表示您想要打印的值。从表面上看,没有任何 base-2 浮点数具有您在这里需要的精度,使用小数从 base 10 到 base 2 来回转换总是会导致舍入错误。

例如,如果您在 IEEE-754 32-bit floatsf32 是)中表示 '9876543210.12345678'(您的字符串可以表示的数字),您将得到:

  • 期望值:9876543210.12345678
  • 最准确的表示:9876543488.00000000
  • 转换错误:277.87654322
  • 二进制表示:01010000 00010011 00101100 00000110
  • 十六进制表示:0x50132c06

甚至f64still makes errors

  • 期望值:9876543210.12345678
  • double中实际存储的值:9876543210.1234569549560546875
  • 转换错误:0.0000001749560546854
  • 二进制表示:01000010 00000010 01100101 10000000 10110111 01010000 11111100 11010111
  • 十六进制表示:0x42026580B750FCD7

不要为此任务使用浮点数。请改用整数。例如,两个整数之间可以打印一个点。

如果您确实需要实际值,请改用 decimal float,这样它实际上可以代表您尝试编码的值。

另一种选择是使用定点整数。换句话说,将数字的所有值移动 8 位小数并将它们表示为整数。然后,打印时再次添加点。就您而言,您很幸运;如果你将9876543210.12345678存储为整数987654321012345678,它仍然适合64位,所以你可以使用u64来表示它。事实上,鉴于您的示例似乎在谈论一笔钱,这很可能就是它的意图。

【讨论】:

    猜你喜欢
    • 2022-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 2019-12-03
    • 1970-01-01
    • 1970-01-01
    • 2018-01-17
    相关资源
    最近更新 更多