将float转换为std :: string而不损失精度。我也不想使用sprintf

时间:2019-01-25 10:24:10

标签: c++

我想转换浮点值,即std :: string中的3.14159267 我不想使用sprintf

#include <iostream>   // std::cout
#include <string>     // std::string, std::to_string

int main ()
{
  std::string pi = "pi is " + std::to_string(3.14159267);
  std::cout<<pi<<std::endl;
  return 0;
}

我得到的结果是     3.141593

3 个答案:

答案 0 :(得分:4)

如果只想打印:

std::cout<< std::setprecision(9) << 3.14159267 << std::endl;

如果要设置字符串的精度:

  double pi = 3.14159265359;
  std::stringstream stream;
  stream << std::setprecision(9) << pi;
  std::string pi_string = stream.str();
  std::cout<< "Pi:" << pi_string << std::endl;

答案 1 :(得分:2)

我建议您使用格式说明符snprintf来调用"%.16g"-该格式说明符以十进制有效数字显示double的十进制形式。有关更多详细信息,请参见Number of Digits Required For Round-Trip Conversions。例如:

inline std::string as_string(double value) {
    char buf[32];
    return std::string(buf, std::snprintf(buf, sizeof buf, "%.16g", value));
}

*printf函数是基本的转换例程,其他所有函数都使用这些例程。

std::to_string在GNU C ++标准库中可以做到:

inline string to_string(double __val)  {
  const int __n =  __gnu_cxx::__numeric_traits<double>::__max_exponent10 + 20;
  return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n, "%f", __val);
}

std::ostream还会在后台调用*snprintf来格式化数字。


还要注意,3.14159267doublefloat常数需要后缀f,例如3.14159267f

答案 2 :(得分:1)

从理论上讲,这应该与C ++ 17兼容的编译器一起工作(并且应该是快速且与语言环境无关的):

#include <charconv>

const double pi = 3.14159267;
const int prec = 6;
char buffer[100];

auto [ptr, ec] = std::to_chars(buffer, std::end(buffer),
    pi, std::chars_format::fixed, prec);

不幸的是,即使是gccclang的主干版本也没有。似乎P0067R5实施起来并不那么明显,另请参见cppreference compiler support(搜索“ P0067R5”)或this reddit thread