【问题标题】:C++ Float Truncation & set precision logic errorC ++浮点截断和设置精度逻辑错误
【发布时间】:2012-10-21 03:58:08
【问题描述】:

我找了一会儿,在这里找不到答案,但这似乎是一种奇怪的问题。我正在使用 C++ 中的 fstream 库。我要做的是从输入文件中获取数据,为其分配变量,然后将其输出到屏幕和输出文件。这就是我正在进行的一个计算汽车贷款每月付款的项目的全部内容,这就是变量以它们的方式命名的原因。

我的数据文件如下所示:

105670.00 12345.00 0.057 4

基本上正在发生的事情是我丢失了前两个数字的小数点后的所有内容(不管我输入的小数点是什么),但它不会发生在第三个数字上。此外,当我尝试设置前两个数字的精度(2)时,我得到一个奇怪的逻辑错误,我将在我的代码之后显示。

我的代码如下所示:
#include<fstream>
#include<iomanip>
#include<iostream>
using namespace std;

int main ()
{
ifstream din; // These are my input and output files
ofstream dout;
float purchasePrice; // The first number of the input file.
float downPayment; // Second number.
float annualInterest; // Third number.
float numYears; // Last number.

// declaring the input/output files code here

din >> purchasePrice >> downPayment >> annualInterest >> numYears;

cout << purchasePrice << endl;
cout << downPayment << endl;
cout << annualInterest << endl;
cout << setprecision(2) << purchasePrice << endl;
cout << setprecision(2) << downPayment << endl;
cout << setprecison(2) << annualInterest << endl;
}
这是我的输出:

105670 12345 0.057 1.1e+005 1.2e+004 0.057

我希望我的输出是:

105670.00 12345.00 0.057 105670.00 12345.00 0.05

此外,在执行任何计算时,数字的行为就好像它们仍然具有小数点后的所有内容。我的问题是,为什么只有一些浮点数被截断,为什么 setprecision() 在这种情况下不能按照预期的方式工作?

非常感谢任何回复,很抱歉解释这么长。

【问题讨论】:

    标签: c++ file-io io floating-accuracy truncation


    【解决方案1】:

    您还需要将fmtflags 设置为fixed

    std::cout << std::fixed << std::setprecision(2) << purchasePrice << "\n";
    

    如果不指定scientificfixed,输出机制将使用任何被认为是最佳的方案。你知道什么是“最好的”,那就是定点方案。详情请见http://en.cppreference.com/w/cpp/io/manip

    更好的是在处理金钱时根本不使用浮点数。使用一些定点算术包要好得多。

    【讨论】:

    • 感谢大卫,这完全解决了我的问题。
    【解决方案2】:

    float 通常具有 24 位二进制精度,这意味着它可以存储大约 6 位精度的十进制数字,因此如果您的数字大于 100000,您将无法获得任何十进制数字的精度。

    您应该使用 double,在这种情况下,它的精度约为 15 位小数,而不是 float

    这很可能回答了您的具体问题,但如果这是为了钱,您可能根本不应该使用浮动格式,因为它们不能准确地将 0.01 表示为一个值,因此您的所有计算都是近似值在处理金钱时,您可能不希望这样。通常将便士/美分/任何整数的数量保存在整数中并要小心:) 甚至更好的是专门为处理货币价值而设计的类,因为通常对四舍五入等有法律要求。

    【讨论】:

    • 我将 purchasePrice 和 downPayment 更改为 doubles,重新运行程序,得到完全相同的输出。我认为这可能也与浮点数据类型的准确性有关,但似乎并非如此。
    • 好的,我同意这不是您问题的答案。尽管您非常接近浮点中可用的精度,但它作为评论可能仍然有效:)
    猜你喜欢
    • 2012-06-23
    • 2012-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多