c++ - 为什么这个浮点数的总和是四舍五入的?
问题描述
我编写了一个简单的 C++ 宏,用于 CERN ROOT 数据分析框架。它接收一个包含天、小时、分钟、秒和亚秒列的数据文件(本质上是电子表格)。我的目标是将该数据转换为时间戳文件,以秒为单位。一切正常,直到添加亚秒。出于某种原因,它似乎对结果进行了四舍五入。例如,一个时间戳是:
804267 + 0.5606663227081298828125 = 804267.5625
另一个是:
155034 + 0.0958281949540391919293 = 155034
ROOT::RDataFrame d("N", "mydata1.root");
TFile *rfout = new TFile("./mydata2.root", "recreate");
TNtuple *N = new TNtuple("N","N","TIMESTAMP");
vector<float> timestamp;
int i;
d.Foreach([&](float day){timestamp.push_back(day*86400.00);},{"day"});
d.Foreach([&](float hr){timestamp.at(i) = timestamp.at(i)+(hr*3600);i++;},{"hr"});
i=0;
d.Foreach([&](float min){timestamp.at(i) = timestamp.at(i)+(min*60);i++;},{"min"});
i=0;
d.Foreach([&](float sec){timestamp.at(i) = timestamp.at(i)+sec;i++;},{"sec"});
i=0;
float j;
d.Foreach([&](float sub){
while(sub > 1){
sub = sub/10;
}
j = sub + timestamp.at(i);
N->Fill(j);
std::cout << std::setprecision(100) << j << " " << sub <<std::endl;
i++;
},{"subsecond"});
rfout->Write();
rfout->Close();
abort();
}`
解决方案
出于某种原因,它似乎对结果进行了四舍五入。
原因命名为IEEE_754。如果您想最大程度地减少求和浮点数的损失,请按从小到大的顺序求和。
所以,在你的情况下:
...
vector<float> timestamp(d.Size(), 0.0f); // Note: I guess, ROOT::RDataFrame has the member function Size()
d.Foreach([i=0,×tamp]mutable(float sub){timestamp[i]+=sub; i++;},{"subsecond"});
d.Foreach([i=0,×tamp]mutable(float sec){timestamp[i]+=sec; i++;},{"sec"});
d.Foreach([i=0,×tamp]mutable(float min){timestamp[i]+=min*60; i++;},{"min"});
d.Foreach([i=0,×tamp]mutable(float hr){timestamp[i]+=hr*3600; i++;},{"hr"});
...
for(const auto &j : timestamp) {
N->Fill(j);
std::cout << std::setprecision(100) << j << " " << sub <<std::endl;
}
推荐阅读
- firebase - Cloud Firestore 数据是否跨大陆复制?
- amazon-web-services - 如果更新成功,有没有办法进行比较更新并触发 lambda 函数?
- swift - 如何在 Swift 中设计一个通用的观察者模式协议?
- reactjs - 为什么文本在反应中不匹配?
- javascript - 当元素快速调整大小时,JavaScript 的 offsetWidth 和 offsetHeight 给出错误的值
- python - 如何在python中对集合进行排序?
- webpack - 带有 Shopify Slate 主题的 jQuery
- jquery - $("select#mySelect option[value='option1']").remove() 当“select#mySelect”实际上是一个jQuery选择器?
- laravel-nova - 使用现有模板在 Nova 中导出 Excel
- json - 搜索端点中的 WP REST API (wp json) 不返回完整数据