std :: string to float(通过std :: stof)精度

时间:2015-07-14 19:58:08

标签: c++ floating-accuracy

我试图解决这个问题,市场数据将货币值返回为数字长度后8位的字符串。

money = "124.19000540"

我需要这个是124.19,任何想法如何实现这个?

std::stof(money) = 124.19000244

如何克服这个问题?

6 个答案:

答案 0 :(得分:5)

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

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

这将做&#34;截断&#34;四舍五入,总是向下舍入。如果您想要四舍五入到最近的分数&#34;,请尝试:

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

正如其他人提到的,你可能想要一个固定点或十进制库,而不是这么简单。

答案 1 :(得分:0)

你可以这样做:

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

答案 2 :(得分:0)

如果您对boost libraries感到满意,那么我建议您使用boost.Lexical_cast。它是一个使用与c ++强制转换相同语法的库(static_castdynamic_cast

这是一个代码示例

#include <boost/lexical_cast.hpp>

...

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

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

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

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

答案 3 :(得分:0)

感谢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 =&gt; CENTS =&gt; USD(string)124.19129999 =(double)124.191300 =(uint   分)12419现在:124.19美元

     

BTC =&gt; SATOSHI =&gt; BTC(string)1.12345678 =(double)1.123457 =(uint   satoshi)112345678现在:1.12345678BTC

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

答案 4 :(得分:0)

您可以使用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

答案 5 :(得分:0)

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

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