std::string 浮动(通过 std::stof)精度

std::string to float (via std::stof) precision

我正在尝试解决这个问题,市场数据 returns 货币价值作为一个字符串,在数字长后 8 位。

money = "124.19000540"

我需要这个是 124.19,知道如何实现吗?

std::stof(money) = 124.19000244

如何克服这个问题?

确保 #include <iomanip> setprecision 并检查函数拼写是否正确。

std::ostringstream out;
out << std::setprecision(2) << std::stof(money);
float percise = std::stof(out.str())

如果您对 boost libraries 感到满意,那么我建议您使用 boost.Lexical_cast。它是一个使用与 c++ 强制转换 (static_cast, dynamic_cast)

相同语法的库

这是一个代码示例

#include <boost/lexical_cast.hpp>

...

double money = boost::lexical_cast<double>("4.82748");

它还可以与许多其他方向一起投射另一个方向。看看the docs.

然后为了获得精度,你可以这样做:

money = (int)(money * 100) * 100;

浮点类型不适合保存货币值。如果您满足于四舍五入到美分,并将钱存储为美分的整数(这是最简单的解决方案之一),您可以这样做:

long numCents = static_cast<long>(100 * std::stof(money))

这将进行 "truncating" 舍入,它总是向下舍入。如果您想四舍五入 "to the nearest cent",请尝试:

long numCents = static_cast<long>(100 * std::stof(money) + 0.5)

正如其他人提到的,您可能想要使用定点或十进制库而不是这么简单的东西。

感谢 brenns10,这是我想出的。

std::string strUSD          = "124.19129999";
double fUSD                 = std::stod(strUSD);
uint64_t uiCents            = USD2CENTS(fUSD);
double fUSDBack             = CENTS2USD(uiCents);

printf("USD / CENTS\n");
printf("(string)%s = (double)%lf = (uint cents)%llu\n", strUSD.data(), fUSD, uiCents);
printf("Present: %.2fUSD\n", fUSDBack);
printf("\n");

std::string strBTC          = "1.12345678";
double fBTC                 = std::stod(strBTC);
uint64_t uiSatoshi          = BTC2SATOSHI(fBTC);
double fBTCBack             = SATOSHI2BTC(uiSatoshi);
printf("BTC / SATOSHI\n");
printf("(string)%s = (double)%lf = (uint satoshi)%llu\n",strBTC.data(),fBTC,uiSatoshi);
printf("Present: %.8fBTC\n", fBTCBack);


// Convert BITCOIN to SATOSHIs
uint64_t CSystemUtil::BTC2SATOSHI(const double& value)
{
    return static_cast<uint64_t>(value * 1e8 + (value < 0.0 ? -.5 : .5));
}
// Convert SATOSHIS to BITCOIN
double CSystemUtil::SATOSHI2BTC(const uint64_t& value)
{
    return static_cast<double>(value/1e8);
}
// Convert CENT to USD
double CSystemUtil::CENTS2USD(const uint64_t& value)
{
    return static_cast<double>(value)/100;
}
// Convert USD to CENT
uint64_t CSystemUtil::USD2CENTS(const double& value)
{
    return static_cast<uint64_t>(value * 100);
}

输出:

USD => CENTS => USD (string)124.19129999 = (double)124.191300 = (uint cents)12419 Present: 124.19USD

BTC => SATOSHI => BTC (string)1.12345678 = (double)1.123457 = (uint satoshi)112345678 Present: 1.12345678BTC

值得注意的是,请查看显示双精度值的 printf。

你可以使用setprecision

#include <iostream> //for std::fixed
#include <sstream> //for std::stringstream
#include <iomanip> //for std::setprecision


int main()
{
  std::string money;
  std::cout << "Enter amount: ";
  getline(std::cin, money);

  std::stringstream out;
  out << std::fixed << std::setprecision(2) << std::stof(money);
  float fmoney = std::stof(out.str());
  std::cout << "Result: " << fmoney << std::endl;

  return 0;
}

执行输出:

Enter amount: 124.19000540
Result: 124.19

而不是 std::stof(),它将字符串转换为浮点数, 您应该使用 std::stod(),将其转换为双精度数(精度更高)。

但正如其他人所说,由于浮点数的表示方式,即使这样,您也常常无法获得完全相同的数字。通过std::cout打印时,可以用<< std::setprecision(<precision>)控制打印的位数。