如何解决如何在C ++中用N个小数来字符串化分数
我想在C ++中以可变精度对一小部分无符号整数进行字符串化处理。因此,1/3
将使用0.33
中的precision
打印为2
。我知道float
和std::ostream::precision
可用于快速而肮脏的解决方案:
std::string stringifyFraction(unsigned numerator,unsigned denominator,unsigned precision)
{
std::stringstream output;
output.precision(precision);
output << static_cast<float>(numerator) / denominator;
return output.str();
}
但是,这还不够好,因为float
的精度有限,并且实际上不能准确表示十进制数。我还有什么其他选择?如果我想输入100位左右,或者出现小数重复,甚至double
都将失败。
解决方法
始终可以执行长除法以逐位数进行字符串化。注意结果由整数部分和小数部分组成。我们可以通过使用/
运算符简单除法并调用std::to_string
来获得不可或缺的部分。对于其余部分,我们需要以下功能:
#include <string>
std::string stringifyFraction(const unsigned num,const unsigned den,const unsigned precision)
{
constexpr unsigned base = 10;
// prevent division by zero if necessary
if (den == 0) {
return "inf";
}
// integral part can be computed using regular division
std::string result = std::to_string(num / den);
// perform first step of long division
// also cancel early if there is no fractional part
unsigned tmp = num % den;
if (tmp == 0 || precision == 0) {
return result;
}
// reserve characters to avoid unnecessary re-allocation
result.reserve(result.size() + precision + 1);
// fractional part can be computed using long divison
result += '.';
for (size_t i = 0; i < precision; ++i) {
tmp *= base;
char nextDigit = '0' + static_cast<char>(tmp / den);
result.push_back(nextDigit);
tmp %= den;
}
return result;
}
仅通过将base
用作模板参数,就可以轻松地将其扩展为与其他库一起使用,但是您就不能再使用std::to_string
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。