没有任何内容被截断。你不能截断double
; 它始终具有相同的位数和相同的格式。但是您使用默认精度 (6) 和默认格式输出,它将始终输出 6 个有效数字,仅此而已。
这里有两个问题。第一个很简单:你想要什么格式和精度?有三种可能的格式:默认(将使用固定或科学,具体取决于值,并且精度表示有效数字的最大数量)、固定或科学(其中精度表示后面的位数小数)。因此,根据格式,精度为 6,您的第一个值将是:
default: 9292.31
fixed: 9292.312300
scientific: 9.292312E03
对于您显示的值,固定似乎最合适;但是如果你有非常小的值,它会显示更少的数字,而对于非常大的值,你可以获得一些很长的字符串。
处理这个问题的常用方法是为值所代表的任何内容定义一个操纵器;在这种情况下,我将直接调用它
values
,因为我不知道有关您的应用程序的任何更精确的信息,但您可能应该找到一个更有意义的名称:
class value
{
mutable std::ostream* myOwner;
mutable std::ios_base::fmtflags myFlags;
mutable int myPrecision;
void capture( std::ostream& owner )
{
if ( myOwner == NULL ) {
myOwner = &owner;
myFlags = myOwner->fmtflags();
myPrecision= myOwner->precision();
}
}
public:
value() : myOwner( NULL ) {}
~value()
{
if ( myOwner != NULL ) {
myOwner->flags( myFlags );
myOwner->precision( myPrecision );
}
}
friend std::ostream& operator<<( std::ostream& dest, value const& manip )
{
manip.capture( dest );
dest.setf( std::ios_base::fixed, std::ios_base::floatfield );
dest.precision( 6 );
}
};
这也将恢复完整表达式末尾的格式化状态(因为它只能用作临时);这通常是一个好主意,因为它可以防止以后代码中出现意外。如果您正在做任何重要的输出,您将创建一个用于保存和恢复的基类,并从中派生您的实际操纵器。
一旦你有了这个,你可以写:
std::cout << value() << a << " " << b << " " << c << std::endl;
语句中后面的所有值value()
都将以所需的格式输出。
更一般地说,您了解机器浮点的工作原理吗?存储在双精度中的实际值不会是您在文件中看到的值,因为您在文件中看到的值不能以通常的双精度格式表示。对于您输入的位数,如果您输出相同的位数,或者甚至更多位数,您应该不会看到任何差异,但如果您输出的位数非常多(比如大约 17 个),则可以。