2010-03-14 81 views
1

您好我阅读文件如下ANSI-C的fscanf问题

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

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

我的问题是,在该文件中比方说,我有一些浮点,让我们说,最多两个数字点后。但是当我要求c使用不同的格式打印这些值时,例如%lf,%。2lf,%。4lf ...它开始播放数字......我唯一担心的是,如果我已经说过了1343.23在文件中,那么c将使用这个值,就像它在计算中一样,或者它将与点后面的数字一起玩。如果它会播放,那么如何才能使它完全按照原样使用浮点数?例如在最后一种情况下,即使我要求它使用%.10lf打印该值,我希望它只打印1343.2300000000。非常感谢!

回答

2

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

此外,您还可以简化&*(x)x,所以你应该写p1+ip2+ip3+ifscanf通话。

+1

这是一个很好的链接,但根据定义,浮点数不是*近似值。确实,你不能在一个范围内表示每个浮点数(因为它们的数目是无限的),但根本不存在1/2或1/4或1/64的近似值。 – paxdiablo 2010-03-14 08:44:52

+1

@paxdiablo:给定一个实际浮动的'x',当然它代表一个确切的数字。但是,'x'也表示范围(假设)为0.5 *(x + nextafter(x,-infinity))'到0.5 *(x + nextafter(x,infinity))'的无限多个实数。我承认在这里有两种不同的思维方式 - 一种方法是将任何浮点数作为范围,另一种方法是将其表示为确切数字。 5年前,comp.lang.c上有一段很长的话题,论点很好:http://groups.google.com/group/comp.lang.c/msg/beacbe60f477d2f2 – 2010-03-14 09:19:50

+1

采取的观点,@Alok,您的观点作为范围的数字当然是有效的。 +1。 – paxdiablo 2010-03-14 10:40:48

0

点后面的位数对fscanf没有任何影响。你应该摆脱& *的东西,一个新的行添加到字符串的结尾:

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

当你的字符串1343.23在读,认为这是一个十进制数,它被转换为计算机的内部二进制表示。使用格式说明符输出将从二进制转换为十进制。在输出中,如果您要求小数点后的数字不同,您可能得不到完全相同的值。一个特定的浮点十进制数可能无法在有限长的二进制浮点数中精确表示,因此应该预期舍入。

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

+0

我至少可以肯定100%,它将在计算中精确使用1343.23000000000?或者至少我该如何强制它在计算中完全按照1343.230000来使用它? – mongoose 2010-03-14 07:37:18

+0

对于正常的二进制浮点数,你不能。您的十进制值(例如1342.23)可能无法表示为二进制浮点数。如果你必须有完美的准确性(例如财务计算),那么使用整数,或者使用一个库来进行小数运算。 – 2010-03-14 07:41:21

+0

@mongoose。 (假设)0和1之间存在无限多的实数。在浮点数中只有有限的可用位数。所以通过简单的逻辑,你不能用任何有限的比特数来表示所有的实数。你真的应该阅读链接的文件。 – 2010-03-14 07:42:35