快速观察给定精度将双精度转换为字符串 [英] Convert double to string quickly observing given precision

查看:62
本文介绍了快速观察给定精度将双精度转换为字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用 SDLC++ 程序.在渲染过程中,我需要绘制一些图形组件.我有时需要将 double 变量(四舍五入到一位小数)转换为 std::string.

I have a C++ program using SDL. During rendering, I need to draw some graphics components. I sometimes need to convert double variables, rounded to one decimal, to std::string.

为此,我目前正在使用 ostringstream 对象并且它工作正常.

For this, I'm currently using a ostringstream object and it works fine.

std::ostringstream ss;
ss << std::fixed << std::setprecision(1) << x;

但是,我想知道这种转换变量的方式在性能方面是否是一个好主意.

However, I'm wondering if this way of converting variables is a good idea with regards to performance.

我试图用 std::to_string(std::round(x * 10)/10))double 变量进行四舍五入,但它没有t 工作 - 我仍然得到像 2.500000000 这样的输出.

I've tried to round the double variables with std::to_string(std::round(x * 10) / 10)), but it didn't work -- I still got output like 2.500000000.

  • 还有其他解决方案吗?
  • ostringstream 是否会产生大量成本?
  • Is there another solution?
  • Does ostringstream incur a heavy cost?

推荐答案

你不能用 std::to_string 指定精度,因为它直接等价于 printf 带参数 %f(如果使用 double).

You can't specify the precision with std::to_string as it is a direct equivalent to printf with the parameter %f (if using double).

如果您担心不会每次都分配流,您可以执行以下操作:

If you are concerned about not allocating each time the stream, you can do the following :

#include <iostream>
#include <sstream>
#include <iomanip>

std::string convertToString(const double & x, const int & precision = 1)
{
    static std::ostringstream ss;
    ss.str(""); // don't forget to empty the stream
    ss << std::fixed << std::setprecision(precision) << x;

    return ss.str();
}


int main() {
    double x = 2.50000;

    std::cout << convertToString(x, 5) << std::endl;
    std::cout << convertToString(x, 1) << std::endl;
    std::cout << convertToString(x, 3) << std::endl;

    return 0;
}

它输出(参见 Coliru):

2.50000

2.5

2.500

虽然我没有检查性能......但我认为你可以通过将它封装到一个类中来做得更好(比如只调用 std::fixedstd::精度一次).

I didn't check the performance though... but I think you could even do better by encapsulating this into a class (like only call std::fixed and std::precision once).

否则,您仍然可以使用带有适合您的参数的 sprintf.

Otherwise, you could still use sprintf with the parameters that suits you.

更进一步,使用封装类,您可以将其用作静态实例或另一个类的成员......如您所愿(查看 Coliru).

Going a little further, with an encapsulating class that you could use as a static instance or a member of another class... as you wish (View on Coliru).

#include <iostream>
#include <sstream>
#include <iomanip>

class DoubleToString
{
public:
    DoubleToString(const unsigned int & precision = 1)
    {
        _ss << std::fixed;
        _ss << std::setprecision(precision);
    }

    std::string operator() (const double & x)
    {
        _ss.str("");
        _ss << x;
        return _ss.str();
    }

private:
    std::ostringstream _ss;

};


int main() {
    double x = 2.50000;

    DoubleToString converter;

    std::cout << converter(x) << std::endl;

    return 0;
}

<小时>

另一种不使用 ostringstream 的解决方案(查看 Coliru) :

#include <iostream>
#include <string>
#include <memory>

std::string my_to_string(const double & value) {
  const int length = std::snprintf(nullptr, 0, "%.1f", value);

  std::unique_ptr<char[]> buf(new char[length + 1]);
  std::snprintf(buf.get(), length + 1, "%.1f", value);

  return std::string(buf.get());
}

int main(int argc, char * argv[])
{

    std::cout << my_to_string(argc) << std::endl;
    std::cout << my_to_string(2.5156) << std::endl;

}

这篇关于快速观察给定精度将双精度转换为字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆