当给定输入var exports = module.exports = {};
const lineReader = require('line-reader');
const Obj = require("./Data")
const Data = Obj.Data;
Promise = require('bluebird');
var eachLine = Promise.promisify(lineReader.eachLine);
var records = [];
exports.readAllLines = async function() {
await eachLine('./datafile.dat', function (line) {
parseLine(line);
});
return records;
}
function parseLine(inputLine) {
var splitArray = inputLine.split("\t");
var date = new Date(Date.parse(splitArray[0]));
var o= splitArray[1];
var h= splitArray[2];
var l= splitArray[3];
var c= splitArray[4];
var v= splitArray[5];
var dataObject = new Data (date, o, h, l, c, v);
records.push(dataObject);
}
时,我希望输出是数学上正确的答案150
,但是我得到了错误的输出70685.7750
。
70685.7812
答案 0 :(得分:4)
float
和double
的数字在内存中的显示不十分准确。主要原因是内存有限,而大多数非整数不是。
最好的例子是PI
。您可以根据需要指定任意多个数字,但仍然是一个近似值。
表示数字的精度有限是以下规则的原因:
在处理
floats
和double
数字时,不要检查是否相等(m == n
),而是要检查它们之间的差异是否小于某个错误({{1} })
也请注意,如评论中所述,上述规则也不是“所有规则的母体规则”。还有其他规则。
必须对每种特定情况进行仔细的分析,以使应用程序正常工作。
(感谢@EricPostpischil的提醒)
答案 1 :(得分:2)
float
类型的变量通常是IEEE-754 32位浮点数。
数字3.14159
无法完全存储在IEEE-754 32位浮点数中-最接近的值大约为3.14159012
。 150 * 150 * 3.14159012
是70685.7777
,可以在32位浮点数中表示的与此 this 最接近的值是70685.78125
,然后使用{{ 1}},您将看到%.4f
。
对此的另一种思考方式是,您的70685.7812
值最终只能精确到第六个有效数字,因此-当您仅计算一系列乘法时-您的结果也仅精确到第六个有效数字(即n
)。 (在一般情况下,情况可能会更糟-例如,将两个接近值相减会导致相对误差大幅增加。)
如果您切换为使用70685.8
类型的变量(并将double
更改为使用scanf()
),那么您很可能会得到想要的答案。 %lf
通常是64位浮点数,这意味着double
值的表示形式中的错误以及结果很小,不会影响小数点后第四位。
答案 2 :(得分:0)
您是否听说过float
和double
的值并不总是那么准确,精确度有限?您是否听说过float
类型给您带来相当于大约7个十进制数字的精度?这就是这个意思。您的预期答案和实际答案分别为70685.7 7 50和70685.7 8 12,而第七位数字与预期的差不多。
我希望输出结果是数学上正确的答案
很抱歉让您失望,但这是您的错误。通常,当您执行浮点运算时,您从不不会得到数学上正确的答案,始终会得到数学上正确答案的有限精度近似值。
此类问题的规范SO答案在Is floating point math broken?处收集。您可能需要阅读其中的一些答案,以获得更多启示。