将任意长度的浮点数舍入到 n 位
Round arbitrary-length floats to n digits
我已经阅读了与 "rounding to n digits" 相关的大部分 SO 问题。我认为这个问题是独立的,因为它与任意长度浮点数的舍入更相关。
0.56714329040978387299996866221035554975381578718651250813513107922304579308668456669321944696175229455773495728285284421635951688
上面的数字是我正在使用的数字类型的示例。
我了解如何在 C++ 中对数字进行舍入,这很简单。但是,我不明白如何将任意长的数字四舍五入到 n 位。
例如,我可能有一个长为 192 位的数字需要四舍五入为 84 位,或者有一个长为 1831 位的数字需要四舍五入为 293 位。如何使用一个函数(或类似函数)完成此操作?
为清楚起见使用伪代码,但我实际上使用 Boost 多精度 cpp_dec_float 来表示任意精度浮点数而不是标准浮点数:
float round(float num, int digits){
//returns num rounded to n digits
}
我遇到的另一个问题是在尝试将非常长的浮点数舍入为少量数字时。
例如,如果我有一个 1000 位长的数字,我想将它四舍五入到 n 位,我必须执行类似 floor(num * 10^1000)/10^1000)
的操作.这不起作用,因为 10^1000 非常大。一个解决方案是用较小的指数进行多次乘法和除法。
[已编辑 - 更好的解决方案]
四舍五入可以基于:
round(x, precision_unit)=trunc(x/precision_unit+0.5)*precision_unit;
类似于:
using namespace boost::multiprecision;
const uint lower_prec_digits=28;
typedef number<cpp_dec_float<100>> higher_prec;
typedef number<cpp_dec_float<lower_prec_digits>> lower_prec;
const higher_prec eps_div=
std::numeric_limits<
number<cpp_dec_float<lower_prec_digits+1>>
>::epsilon()
;
higher_prec pi(
"3.1415926535"
"8979323846"
"2643383279"
"5028841971"
"6939937510"
"5820974944"
"5923078164"
"0628620899"
"8628034825"
"3421170679"
);
lower_prec round_pie=lower_prec(trunc(pi/eps_div+0.5)*eps_div);
std::cout.precision(100);
std::cout << round_pie << std::endl << pi << std::endl;
结果:
3.1415926535897932384626433833
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068
我已经阅读了与 "rounding to n digits" 相关的大部分 SO 问题。我认为这个问题是独立的,因为它与任意长度浮点数的舍入更相关。
0.56714329040978387299996866221035554975381578718651250813513107922304579308668456669321944696175229455773495728285284421635951688
上面的数字是我正在使用的数字类型的示例。
我了解如何在 C++ 中对数字进行舍入,这很简单。但是,我不明白如何将任意长的数字四舍五入到 n 位。
例如,我可能有一个长为 192 位的数字需要四舍五入为 84 位,或者有一个长为 1831 位的数字需要四舍五入为 293 位。如何使用一个函数(或类似函数)完成此操作?
为清楚起见使用伪代码,但我实际上使用 Boost 多精度 cpp_dec_float 来表示任意精度浮点数而不是标准浮点数:
float round(float num, int digits){
//returns num rounded to n digits
}
我遇到的另一个问题是在尝试将非常长的浮点数舍入为少量数字时。
例如,如果我有一个 1000 位长的数字,我想将它四舍五入到 n 位,我必须执行类似 floor(num * 10^1000)/10^1000)
的操作.这不起作用,因为 10^1000 非常大。一个解决方案是用较小的指数进行多次乘法和除法。
[已编辑 - 更好的解决方案]
四舍五入可以基于:
round(x, precision_unit)=trunc(x/precision_unit+0.5)*precision_unit;
类似于:
using namespace boost::multiprecision;
const uint lower_prec_digits=28;
typedef number<cpp_dec_float<100>> higher_prec;
typedef number<cpp_dec_float<lower_prec_digits>> lower_prec;
const higher_prec eps_div=
std::numeric_limits<
number<cpp_dec_float<lower_prec_digits+1>>
>::epsilon()
;
higher_prec pi(
"3.1415926535"
"8979323846"
"2643383279"
"5028841971"
"6939937510"
"5820974944"
"5923078164"
"0628620899"
"8628034825"
"3421170679"
);
lower_prec round_pie=lower_prec(trunc(pi/eps_div+0.5)*eps_div);
std::cout.precision(100);
std::cout << round_pie << std::endl << pi << std::endl;
结果:
3.1415926535897932384626433833
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068