如果这个问题(和任何答案)以有效数字而不是小数位为框架,会更准确。正如 Itamar Katz 暗示的那样,IEEE 标准确实将双精度浮点数存储在 52 位中作为有效位(有些人称之为尾数)。该标准还暗示了一个额外的位,因此双精度数具有 53 个有效位。当二进制数转换为十进制表示时,这将转换为 15 或 16 位有效数字。
Matlab 和 Visual C++ 都不能(没有额外的工具,例如任意精度库或使用 128 位 fp 数)存储超过标准有效数大小的双精度数。如果您的程序以任何一种语言向您显示超过 15(或 16)位十进制数字的数字,则您不能信任任何多余的数字。它们不是来自数字的存储表示,它们是在内存和屏幕之间的某处添加的——也许一个“有用的”数字格式化程序只是扩展了最右边的数字,直到你看到你请求的 19 位数字(管他呢)。
从如何将数字从 C++ 传输到 Matlab 或从 Matlab 传输数字,甚至您确实传输数字的问题并不完全清楚;也许您只是想编写一个 C++ 程序来重现您的 Matlab 程序的结果。(我们在这里做了很多,所以我在这个领域有一些经验。)
如果您使用“文本”文件,那么您传输的不是数字,而是数字的表示。如果您的程序将文本“15.833”读入一个双精度变量,则对有效数字中额外数字所取的值做出任何假设是不安全的。特别是你不应该假设它们将被设置为 0——好吧,我想对 C++ 更了解的人可能会告诉我们语言标准确实保证了这一点,但 Matlab 没有,我不认为 C++也可以。如果要设置额外的数字,请在文本表示中指定它们。即使这样也不能保证您存储的值与文本文件中指定的完全一致,您的变量将(可能)保存与文本中的值最接近的 fp 数。
但是,如果您的文本文件是由 Matlab(或 C++)编写的,并将 15 或 16 位数字写入数字的文本表示,那么它应该是整个 fp 数字的文本表示,并且在被另一个程序读取时,应该被翻译进入相同的 fp 数。但是请注意,我写的是“应该”,并且该数字至少被翻译了两次,当您将视线从计算机上的数字上移开时,会发生奇怪的事情。
在 C++ 和 Matlab 之间进行位精确数据传输的更好选择是使用二进制文件格式,该格式将 double 的所有 64 位存储为 64 位。Matlab MAT 文件格式当然以标准指定的形式存储 IEEE754 数字。
可能所有前面的废话都与另一个潜在的问题无关。这个问题可能是你的算法不稳定——这是另一个话题。
总结一下:
- 以二进制表示从程序到程序传输数字(无论您完全使用文件还是消息传递或其他机制)。
- 在双精度浮点数的任何十进制表示中,不要信任超过 15 个有效数字。
Furthermore, unless you take special measures in your code, your programs probably gradually lose accuracy as they progress, making all the low-order digits of dubious reality. For the application that you hint at, it's unlikely that the science behind the code supports the hypothesis that two outputs which differ in the 15th significant digit represent different values. What is the accuracy of the measurements on which your inputs are based ?