简体   繁体   English

C语言中的浮点数组

[英]A floating point array in C

我正在开发一个代码,其中我必须一次在文本文件中加载存储在每一行中的浮点值...我使用fscanf()将这些数据中的每一个加载到浮点数组中...但是我发现浮点以不同的方式存储,示例407.18存储为407.179993,414.35存储为414.350006 ...现在我被困住了,因为将数字以它们在文件中的形式存储是绝对重要的,但在这里看来即使本质上是相同的,也各不相同。...我如何获取数字以原始形式存储?

If it's absolutely important that the numbers be stored in the form they were in the file, don't use floating-point values . 如果数字以文件中的格式存储绝对重要, 请不要使用浮点值 Not all fractional base-10 values can be represented exactly in binary. 并非所有以10为底的分数都可以用二进制精确表示。

For details, you should consult the article "What Every Computer Scientist Should Know About Floating-Point Arithmetic" [PDF link]. 有关详细信息,您应该查阅文章“每位计算机科学家应了解的浮点算法” [PDF链接]。

You should store the numbers in string form or as scaled integers. 您应该将数字以字符串形式或以小数位数存储。

What you see is correct since floating point cannot exactly represent many real numbers. 您看到的是正确的,因为浮点不能精确表示许多实数。 This is a must-read: What Every Computer Scientist Should Know About Floating-Point Arithmetic 这是必读: 每位计算机科学家都应了解的浮点运算法则

The C++ float and double types are represented as IEEE floating point numbers. C ++ floatdouble float类型表示为IEEE浮点数。 There are binary floating point numbers, not decimals. 有二进制浮点数,而不是小数。 They don't have infinite precision, and even relatively 'simple' decimal values will change when converted to binary floating point and back. 它们没有无限的精度,甚至当转换为二进制浮点数并返回时,即使是相对“简单”的十进制值也会改变。

Languages that focus on money (COBOL and PL/I, eg) have decimal data types that use slower representations that don't have this problem. 专注于金钱的语言(例如COBOL和PL / I)具有使用较慢表示法的十进制数据类型,而不会出现此问题。 There are libraries for this purpose in C or C++, or you can use scaled integers if you don't need too much range. 在C或C ++中有用于此目的的库,或者如果不需要太多范围,则可以使用小数位整数。

sfactor, A bit of clarification: you state "...absolutely important that the numbers be stored in the form they were in the file" - what 'form' is this? sfactor,需要澄清一点:您声明“ ...将数字以文件中存在的形式存储绝对重要”-这是什么“形式”? I'm assuming a display form?! 我要使用展示形式吗? Here's the deal: If you store in the file 407.18, but it is displayed as 407.179993 - this is totally normal and expected. 达成协议:如果您将文件407.18存储在文件中,但显示为407.179993,这完全正常,可以预期。 When you construct your sprintf or whatever formatted print you are using, you must instruct it to limit the precision after the decimal point. 构造sprintf或要使用的任何格式的打印时,必须指示它限制小数点后的精度。 This should do the trick: 这应该可以解决问题:

#include <stdio.h>
void main(void);
void main()
{
   printf("%.2f",407.179993);
}

You might want to take a look at an existing library that implements floating point with controlled rounding. 您可能想看一下现有的库,该库通过控制舍入来实现浮点数。 I have used MPFR . 我用过MPFR It is fast and open source. 它是快速且开源的。 If you are working with money then a different library would be better. 如果您在用钱工作,那么最好选择其他图书馆。

There is a lot of different ways to store numbers - each with their strenghts and weaknesses. 存储数字的方式有很多-每种都有其优势和劣势。

In your case floating point numbers are not the best choice because they don't represent most real numbers exactly . 在您的情况下,浮点数不是最佳选择,因为它们不能准确地代表大多数实数。

Scaled integers is a case of the common design idiom: separate representation from the presentation. 可缩放整数是常见设计习惯的一种情况:将表示形式与表示形式分开。

Decide on how many digits you want after the decimal point, eg. 确定小数点后要多少位数,例如。 2 digits as in 123,45. 如123,45中的2位数字。 You should then internaly represent the number as the integer 12345. Whenever you display the value to the user you should insert a decimal point at the relevant spot. 然后,应在内部将数字表示为整数12345。无论何时向用户显示该值,都应在相关位置插入小数点。

Short InformIT article on Scaled Integers by Danny Kalev Danny Kalev撰写的有关可缩放整数的InformIT简短文章

Before going overboard on scaled integers do inspect the domain of your problem closely to assert that the "slack" in the floating point numbers is significant enough to warrent using scaled integers. 在过度使用可缩放整数之前,请仔细检查您的问题所在,以断言浮点数中的“松弛”足以使用可缩放整数进行警告。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM