在我之前的问题中,我打印了一个double using cout,当我没有预料到它时,它变得圆润了。我如何才能使cout打印一个双重使用全精度?
当前回答
你可以直接在std::cout上设置精度,并使用std::fixed格式说明符。
double d = 3.14159265358979;
cout.precision(17);
cout << "Pi: " << fixed << d << endl;
您可以#include <limits>来获得浮点数或双精度浮点数的最大精度。
#include <limits>
typedef std::numeric_limits< double > dbl;
double d = 3.14159265358979;
cout.precision(dbl::max_digits10);
cout << "Pi: " << d << endl;
其他回答
这将显示点后小数点后两位的值。
#include <iostream>
#include <iomanip>
double d = 2.0;
int n = 2;
cout << fixed << setprecision(n) << d;
看这里:定点符号
std::固定
使用固定浮点符号设置的浮点字段格式标志 STR流的固定。 当floatfield设置为fixed时,将写入浮点值 使用定点表示法:值完全用as表示 由精度字段指定的小数部分中的多个数字 (精度)和无指数部分。
标准::设置精度
Set decimal precision设置格式化时使用的十进制精度 输出操作上的浮点值。
如果您熟悉表示浮点数的IEEE标准,就会知道在标准范围之外完全精确地显示浮点数是不可能的,也就是说,它总是导致实际值的四舍五入。
您需要首先检查该值是否在作用域内,如果是,则使用:
cout << defaultfloat << d ;
std:: defaultfloat
使用默认浮点符号设置floatfield格式标志 为STR流设置defaultfloat。 当floatfield设置为defaultfloat时,浮点值为 使用默认表示法编写:表示使用尽可能多的表示法 需要的有意义的数字,直到流的十进制精度 (精度),同时计算小数点前后的数字 点(如果有的话)。
这也是cout的默认行为,这意味着您没有显式地使用它。
上ostream::精密(int)
cout.precision( numeric_limits<double>::digits10 + 1);
cout << M_PI << ", " << M_E << endl;
将产生
3.141592653589793, 2.718281828459045
为什么说“+1”我不知道,但你多出来的数字是正确的。
以下是我会使用的方法:
std::cout << std::setprecision (std::numeric_limits<double>::digits10 + 1)
<< 3.14159265358979
<< std::endl;
基本上,限制包具有所有内置类型的特性。 浮点数(float/double/long double)的特征之一是digits10属性。这定义了以10为基底的浮点数的精度(我忘记了确切的术语)。
参见:http://www.cplusplus.com/reference/std/limits/numeric_limits.html 查看其他属性。
最轻松的……
#include <limits>
using std::numeric_limits;
...
cout.precision(numeric_limits<double>::digits10 + 1);
cout << d;
这是一个适用于任何浮点类型的函数,而不仅仅是双精度浮点类型,它还将流放回之后找到它的方式。不幸的是,它不能很好地与线程交互,但这是iostreams的本质。你需要在文件的开头包含以下内容:
#include <limits>
#include <iostream>
这是这个函数,如果你经常使用它,你可以把它放在头文件中:
template <class T>
void printVal(std::ostream& os, T val)
{
auto oldFlags = os.flags();
auto oldPrecision = os.precision();
os.flags(oldFlags & ~std::ios_base::floatfield);
os.precision(std::numeric_limits<T>::digits10);
os << val;
os.flags(oldFlags);
os.precision(oldPrecision);
}
像这样使用它:
double d = foo();
float f = bar();
printVal(std::cout, d);
printVal(std::cout, f);
如果你想使用普通的插入<<操作符,你可以使用额外的包装器代码:
template <class T>
struct PrintValWrapper { T val; };
template <class T>
std::ostream& operator<<(std::ostream& os, PrintValWrapper<T> pvw) {
printVal(os, pvw.val);
return os;
}
template <class T>
PrintValWrapper<T> printIt(T val) {
return PrintValWrapper<T>{val};
}
现在你可以这样使用它:
double d = foo();
float f = bar();
std::cout << "The values are: " << printIt(d) << ", " << printIt(f) << '\n';
推荐文章
- 为什么我的程序不能在Windows 7下用法语编译?
- 如何获取变量的类型?
- 什么是奇怪的重复模板模式(CRTP)?
- 连接两个向量的最佳方法是什么?
- 在c++中,是通过值传递更好,还是通过引用到const传递更好?
- 在STL中deque到底是什么?
- Windows上最好的免费c++分析器是什么?
- 如何自动转换强类型枚举为int?
- 在一个类中使用具有成员函数的泛型std::function对象
- 'for'循环中的后增量和前增量产生相同的输出
- 虚函数和纯虚函数的区别
- c++中的_tmain()和main()有什么区别?
- 内存泄漏是否正常?
- 当启用c++ 11时,std::vector性能回归
- 什么时候使用哪种指针?