简体   繁体   English

C++ printf 四舍五入?

[英]C++ printf Rounding?

My code:我的代码:

   // Convert SATOSHIS to BITCOIN
    static double SATOSHI2BTC(const uint64_t& value)
    {
        return static_cast<double>(static_cast<double>(value)/static_cast<double>(100000000));
    }

    double dVal = CQuantUtils::SATOSHI2BTC(1033468);
    printf("%f\n", dVal);
  printf("%s\n", std::to_string(dVal).data());

Google output: 0.01033468谷歌输出: 0.01033468

Program output: 0.010335 both for printf and std::to_string程序输出: printfstd::to_string均为0.010335

Debugger output: 0.01033468调试器输出: 0.01033468

Do printf and std::to_string round the number? printfstd::to_string对数字进行四舍五入? How do I get a string with the proper value?如何获得具有正确值的字符串?

The std::to_string function uses the same notation as with printf : std::to_string函数使用与printf相同的符号:

7,8) Converts a floating point value to a string with the same content as what std::sprintf(buf, "%f", value) would produce for sufficiently large buf. 7,8) 将浮点值转换为与std::sprintf(buf, "%f", value)为足够大的 buf 产生的内容相同的字符串。

The printf documentation shows: printf文档显示:

Precision specifies the minimum number of digits to appear after the decimal point character.精度指定小数点字符后出现的最小位数。 The default precision is 6.默认精度为 6。

You can use %.32f to indicate how many decimals you want (eg 32):您可以使用%.32f来表示您想要的小数位数(例如 32):

printf("%.32f\n", dVal);

I cannot find a way to change the number of decimals with to_string , but you could print the value to a string with sprintf :我找不到使用to_string更改小数位数的方法,但您可以使用sprintf将值打印到字符串:

char buffer [100];
sprintf (buffer, "%.32f", dVal);
printf ("%s\n",buffer);

And if you want a std::string :如果你想要一个std::string

std::string strVal(buffer);

It's a little tricky with the field width字段宽度有点棘手

#include <iostream>
#include <iomanip>
#include <cmath>
#include <string>
#include <sstream>
#include <limits>

#define INV_SCALE 100000000

static const int      WIDTH   = std::ceil(
                                    std::log10(std::numeric_limits<uint64_t>::max())
                                ) + 1 /* for the decimal dot */;
static const uint64_t INPUT   = 1033468;
static const double   DIVISOR = double(INV_SCALE);
static const int      PREC    = std::ceil(std::log10(DIVISOR));

static const double   DAVIDS_SAMPLE = 1000000.000033;

namespace {
std::string to_string(double d, int prec) {
    std::stringstream s;
    s << std::fixed
      << std::setw(WIDTH)
      << std::setprecision(prec) 
      << d;
    // find where the width padding ends    
    auto start = s.str().find_first_not_of(" ");
    // and trim it left on return
    return start != std::string::npos ? 
                    &(s.str().c_str()[start]) : "" ;
}
}

int main() {
    for (auto& s : 
            {to_string(INPUT/DIVISOR, PREC), to_string(DAVIDS_SAMPLE, 6)} 
        ) std::cout << s << std::endl;

    return /*EXIT_SUCCESS*/ 0;
}

output:输出:

0.01033468
1000000.000033

Thanks to all answers,感谢所有的答案,

this made the trick:这使伎俩:

std::stringstream ss;
ss << std::setprecision(8) << dVal;
std::string s = ss.str();
printf("ss: %s\n", s.data());

Output:输出:

ss: 0.01033468 SS:0.01033468

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM