精确的雷亚尔通过writeln/readln在德尔斐
-
02-07-2019 - |
题
我的客户应用程序出口和进口相当多的变量的类型实际通过的文本文件使用writeln和readln.我已经试过的宽度增加的领域这么写的代码看起来像:
writeln(file, exportRealvalue:30); //using excess width of field
....
readln(file, importRealvalue);
当我出口和再进口和再出口和比较文件我得到一个差异在最后两位数字,e。g(可能是在实际数量的数字在这里但你得到它):
-1.23456789012E-0002
-1.23456789034E-0002
这实际上使一个区别在应用程序,使客户想要知道什么我可以做的。现在我不确定它是只有写入/读,它不会但是我想我会扔一个简单的问题出现之前我潜入嘿叠。我需要去二进制的吗?
这不是一个程序,处理与货币或什么的,我只是写和阅读值向/从文件。我知道浮点是有点奇怪,有时候和我想的一个例行程序(writeln/readln)可能有一些有趣的业务。
解决方案
如果要使用WriteLn指定实数的精度,请使用以下命令:
WriteLn(RealVar:12:3);
它输出Realvar值至少12个位置,精度为3。
其他提示
你可以尝试换来 延长 为更加精确。如指出,虽然,浮点数只有如此多的重要数字的精确度,所以它仍然是可能的,显示更多的数字,然后是准确的储存,这可能导致的行为你规定。
从德尔福帮助:
基本Win32实类型
| Significant | Size in Type | Range | digits | bytes ---------+----------------------------------+-------------+---------- Real | -5.0 x 10^–324 .. 1.7 x 10^308 | 15–16 | 8 Real48 | -2.9 x 10^–39 .. 1.7 x 10^38 | 11-12 | 6 Single | -1.5 x 10^–45 .. 3.4 x 10^38 | 7-8 | 4 Double | -5.0 x 10^–324 .. 1.7 x 10^308 | 15-16 | 8 Extended | -3.6 x 10^–4951 .. 1.1 x 10^4932 | 10-20 | 10 Comp | -2^63+1 .. 2^63–1 | 10-20 | 8 Currency | -922337203685477.5808.. | | 922337203685477.5807 | 10-20 | 8
注意到:六个字节 Real48 类型被称为 真的 在早期版本的对象帕斯卡尔。如果你重新编译代码,使用较旧的六个字节的实类型的德尔斐,你可能想要改变它 Real48.你也可以使用的{$REALCOMPATIBILITY在}编译程序指令转 真的 回到六个字节的类型。以下评论适用于基本的实际类型。
- Real48 保持后向兼容性。由于其储存格式不是原来的英特尔处理器结构,它会导致慢性能比其他浮点类型。
- 延长 提供更精确比其他的实际类型,但是小便携式。小心使用扩展,如果你正在创建数据的文件共享的平台。
注意到范围更大的那位有效数字。所以你可以有一些较大的然后可以准确地储存。我建议四舍五入到显着的位数,以防止这种情况发生。
使用浮点类型时,您应该了解指定类型的精度限制。例如,4字节IEEE-754类型只有大约7.5个有效数字的精度。八字节IEEE-754类型的有效位数大约是其两倍。显然,delphi实数类型的精度大约为11位有效数字。结果是,您指定的格式的任何额外数字可能是噪声,可能导致基数10格式值和基数2浮点值之间的转换。
首先,我会尝试查看是否可以通过使用不同参数的Str或者提高应用中类型的精度来获得任何帮助。 (你尝试过使用Extended吗?)
作为最后的手段,(警告!解决方法!! )我会尝试将客户的字符串表示与二进制表示一起保存在排序列表中。在写回浮点值之前,我会看到表中是否已存在匹配值,其字符串表示形式已知且可以替代使用。为了快速获得此查找,您可以对数值进行排序,并使用二进制搜索来找到最佳匹配。
根据您需要处理的处理量,替代方法可以是将数字保持为BCD格式以保持原始准确度。
如果不知道您的ExportRealValue和ImportRealValue是什么类型,很难回答这个问题。正如其他人所提到的,真实类型都有不同的精确度。
值得注意的是,与某种想法相反,延伸并不总是更高的精度。扩展是10-20个重要数字,其中双倍是15-16。当你在第十个sig fig附近遇到麻烦时,也许你已经使用了扩展。
要获得对读取和写入的更多控制,您可以自己将数字转换为字符串,并将其写入文件流。至少就是这样,你不必担心如果读取和写入背后都没有好处。