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>)
控制打印的位数。
我正在尝试解决这个问题,市场数据 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>)
控制打印的位数。