C++ 为什么不能截断一个双精度?

C++ 为什么不能截断一个双精度?,c++,double,cout,C++,Double,Cout,以下是我的控制台输入/输出 请输入实数:-23486.33 勾选字符:9 多谢各位。 您输入的真实数字是-23486.3 我输入的值是-23486.33,但无法将其打印为-23486.3。 相关代码如下: #include <iostream> #include <string> #include <cctype> using namespace std; // Function prototype (declaration) string readDo

以下是我的控制台输入/输出

请输入实数:-23486.33 勾选字符:9

多谢各位。 您输入的真实数字是-23486.3

我输入的值是-23486.33,但无法将其打印为-23486.3。 相关代码如下:

#include <iostream>
#include <string>
#include <cctype>

using namespace std;

//  Function prototype (declaration)
string readDouble();
bool isValidDouble(string);

int main()
{
    string value;
    double number;

    value = readDouble();
    while (!isValidDouble(value)) {
        cout << "The number you entered is not a valid integer." << endl;
        value = readDouble();
    }

    number = atof(value.c_str());
    cout << "Thank you." << endl
         << "The real number you entered is " << number << endl;
}
#包括
#包括
#包括
使用名称空间std;
//函数原型(声明)
字符串readDouble();
bool-isValidDouble(字符串);
int main()
{
字符串值;
双数;
value=readDouble();
而(!isValidDouble(值)){
你试过了吗

std::cout << std::setprecision(2) << number;

std::cout您可以将精度设置为双精度的最大限制

代码片段如下所示:

#include <iostream>
#include <limits>
#include <iomanip>

using namespace std;
double number = ... // your double value.
cout << setprecision(numeric_limits<double>::digits10) << number << endl; 
#包括
#包括
#包括
使用名称空间std;
double number=…//您的双精度值。

cout在输出double时设置精度,在比较它们时显式保持精度


将十进制数字的字符串表示形式转换为双精度(浮点数字表示形式)时,内存中的数据在数学上可能不等于字符串表示形式。它是浮点数字表示形式的最佳近似值,反之亦然。

-23486.3显示,因为默认情况下,
std::cout
仅打印6位数字。

打印回从标准输入(转换文本)输入的数字→ 浮点数→ 文本),您可以使用
set_precision
digits10
作为精度:

double d = -23486.33;
int precision = std::numeric_limits<double>::digits10;
std::cout << std::setprecision(precision) << d << std::endl;
double d = -23486.33;
int precision = std::numeric_limits<double>::max_digits10;
std::cout << std::setprecision(precision) << d << std::endl;
这将显示:

-23486.33000000002

此处打印的数字不相同,因为-23486.33在IEEE编码中没有精确表示(以基数2表示,而不是以基数10表示)


有关
digit10
max_digit10
的更多详细信息,您可以阅读:



我看到了这一点。这将解决这个特定问题,但我需要上面的程序支持小数点后两位以上的双精度。@Mickster37:浮点值存储在二进制中,而不是十进制中,因此某些十进制值仅表示为二进制的近似值。使用
float
double
@Mickster:特别是
-23486.3
-23486.30
@dreamlax之间没有区别,我了解得很清楚。如果我的数字有很多小数点,我不会期望一个精确的小数点,但小数点位置很少的数字也是这样吗?@MSalters否,但-23486.33和-23486.3之间存在差异。为了避免过长的输出,需要进行一些舍入。例如,与十进制-23486.33最接近的IEEE 754 64位二进制是-23486.3300000000174622982740402216796875。在这种情况下,这可能是
数字的值我的编号(调试器显示的值为-23486.33)到-23486.3?即使数字是一个小数位数过多的数字,如您的示例中所示,为什么要一直修剪到0集之后?ostream格式基于宽度和精度,而不是数字的值。相反,Java的Double-toString将Double转换为最短的字符串,以转换back到同一个双精度。它会将您的数字显示为-23486.33。@PatriciaShanahan现在有意义了。这到底是做什么的?更多的注释会很有帮助。@Mickster37它将精度设置为双精度的最大限制,并修复了格式说明符,它可以修剪不需要的非常有用的代码段!我正在给某人一个正确的答案虽然是谁更直接地回答了这个问题。谢谢。@DanielLaügt嗨Daniel,
setprecision
设置小数点前后的数字精度。通过数字
-23456.11111111 9112345
-123456.11111 9112345
很容易测试,它们将是
-23456.11111 91
,并且<代码>-123456.11111111 9
分别。@DanielLaügt是的,应该删除已修复。可以理解。但是,正如我在原始帖子中所述,当使用调试器检查“number”的值时,显示为-23486.33,但它打印出-23486.3。在我看来,精度损失发生在打印浮点时,而不是从字符串转换为浮点时。@Mickster37内存中的数据可能不仅仅是-23486.33。它可能是-23486.330000000002。程序不知道精度(用于输出)你想要的。所以它决定给你。这很有道理。很好的解释。