【问题标题】:ansi-c fscanf problemansi-c fscanf问题
【发布时间】:2010-03-14 07:20:27
【问题描述】:

你好,我读的文件如下

       fscanf(fp,"%f %f %f\n",&*(p1+i), &*(p2+i), &*(p3+i));

我的文件行由三个浮点数组成...

我遇到的问题是,在文件中假设我有一些浮点数,假设点后最多两位数。但是当我要求 c 使用不同的格式打印这些值时,例如 %lf,%.2lf,%.4lf...在文件中,然后 c 将完全按照计算中的方式使用该值,否则它将使用点后面的数字。如果它会播放,那么如何才能使它完全使用浮点数呢?例如,在最后一种情况下,即使我要求它使用 %.10lf 打印该值,我也希望它只打印 1343.2300000000.?非常感谢!

【问题讨论】:

    标签: c programming-languages file


    【解决方案1】:

    “问题”是浮点数在定义上是近似的。您应该阅读What Every Computer Scientist Should Know About Floating-Point Arithmetic 了解更多信息。

    此外,您可以将&*(x) 简化为x,因此您应该在您的fscanf 调用中写入p1+ip2+ip3+i

    【讨论】:

    • 这是一个很好的链接,但根据定义,浮点数不是近似值。确实,您不能代表一个范围内的每个浮点数(因为它们的数量是无限的),但是 1/2 或 1/4 或 1/64 根本就没有近似值。
    • @paxdiablo:给定一个真正的浮动x,当然它代表一个确切的数字。但是,x 也代表无限多的实数,范围(比方说)0.5*(x + nextafter(x, -infinity))0.5*(x + nextafter(x, infinity))。我承认这里有两种不同的思维方式 - 一种方法是将任何浮点数表示为一个范围,另一种方法是将其表示为精确的数字。 5 年前在 comp.lang.c 上有一个很长的帖子,有很好的论据:groups.google.com/group/comp.lang.c/msg/beacbe60f477d2f2
    • 指出,@Alok,您将数字视为范围的观点当然是有效的。 +1。
    【解决方案2】:

    当您读入字符串 1343.23 时,将其视为十进制数,将其转换为计算机内部的二进制表示。使用格式说明符输出从二进制转换为十进制。在输出时,如果您要求小数点后的位数不同,您可能不会得到完全相同的值。特定的浮点十进制数可能无法在有限长度的二进制浮点数中精确表示,因此应该进行四舍五入。

    如需更好的解释,请参阅著名文章What Every Scientist Should Know About Floating-Point Arithmetic

    【讨论】:

    • 我是否可以至少 100% 确定它将在计算中准确使用 1343.23000000000?或者至少我怎样才能强制它在计算中完全像 1343.230000 一样使用它?
    • 对于普通的二进制浮点数,你不能。您的十进制值(例如 1342.23)可能无法表示为二进制浮点数。如果您必须具有完美的准确性(例如,金融计算),请使用整数,或使用库进行十进制运算。
    • @mongoose。在(假设)0 和 1 之间有无限多个实数。浮点数中只有有限数量的可用位。因此,通过简单的逻辑,您不能使用有限位数的任何表示来表示所有实数。你真的应该阅读链接的文档。
    • @mongoose:十进制数 1342.23 没有在写成二进制扩展时没有有限的精确表示 - 这与您无法精确表示的方式完全相似数字 1/3 作为有限的精确十进制扩展。
    【解决方案3】:

    点后的位数对 fscanf 没有任何影响。你应该去掉 &* 的东西并在字符串的末尾添加一个新行:

    fscanf(fp, "%f %f %f\n", p1 + i, p2 + i, p3 + i);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-24
      • 1970-01-01
      • 1970-01-01
      • 2011-04-16
      • 2010-11-06
      相关资源
      最近更新 更多