C++ 小数点位置

C++ decimal placement

当我为输入问题输入 2.785 时,输出将显示变量问题为 2.79,我该怎么做?

我尝试使用 setprecision,但出于某种原因它无法正常工作,除非我做错了

这是用户输入的问题及其内容:

Enter positive daily growth % (.1 must be entered as 10):
user enters "2.785"
output -> 0.02785

我想要的输出应该是这样的:

desired output-> 2.79%

感谢任何帮助。我知道这对其他人来说可能看起来很简单,但我已经尝试过在线查找,但我发现的所有内容都没有意义或不起作用,我不知道我做错了什么。

浮点运算

之所以具有挑战性,是因为当你对它们进行运算时,浮点数无法准确表示。 See wikipedia article

这是一个很有趣的话题,如果你有一点时间,看看关于浮点的解释以及它在计算机中的表示方式。


如果您只寻找显示(仅适用于小数位)

如果您只想显示较小的值,可以使用以下代码:

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

using namespace std;

string truncateAsString(double n, int precision) {
    stringstream ss;
    double remainder = static_cast<double>((int)floor((n - floor(n)) * precision) % precision);
    ss << setprecision(numeric_limits<double> ::max_digits10 + __builtin_ctz(precision))<< floor(n);
    if (remainder)
        ss << "." << remainder;
    cout << ss.str() << "%" << endl;
    return ss.str();
}

int main(void) {
    double a =  0.02785;
    int precision = 100; // as many digits as you add zeroes. 3 zeroes means precision of 3.
    string s = truncateAsString(a*100 + 0.5 / 100, precision);
    return 0;
}

寻找真正的价值?

也许您正在寻找浮点数的真实值,您可以使用 boost multiprecision library

The Boost.Multiprecision library can be used for computations requiring precision exceeding that of standard built-in types such as float, double and long double. For extended-precision calculations, Boost.Multiprecision supplies a template data type called cpp_dec_float. The number of decimal digits of precision is fixed at compile-time via template parameter.

你需要使用像boost/multiprecision这样的自定义库,因为浮点数不够精确,请看我下面的代码:

#include <boost/math/constants/constants.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <iostream>
#include <limits>
#include <cmath>
#include <iomanip>

using namespace std;
using boost::multiprecision::cpp_dec_float_50;

cpp_dec_float_50 truncate(cpp_dec_float_50 n, int precision) {
    cpp_dec_float_50 remainder = static_cast<cpp_dec_float_50>((int)floor((n - floor(n)) * precision) % precision) / static_cast<cpp_dec_float_50>(precision);
    return floor(n) + remainder;
}

int main(void) {
    int precision = 100; // as many digits as you add zeroes. 5 zeroes means precision of 5.
    cpp_dec_float_50 n =  0.02785 * 100;
    n = truncate(n + 0.5/precision, precision); // first part is remainder, floor(n) is int value truncated.
    cout << setprecision(numeric_limits<cpp_dec_float_50> ::max_digits10 + __builtin_ctz(precision)) << n << "%" << endl; // __builtin_ctz(precision) will equal the number of trailing 0, exactly the precision we need!
    return 0;
}

输出(两种情况)

2.79%

注意:我将 0.5 / precision 添加到截断函数以强制它像舍入一样。