![](/img/trans.png)
[英]Remove all trailing zeros from a double while formatting in a string in C++
[英]Remove Trailing Zeros After Decimal C++
我一直在尝试做一件非常简单的事情,这需要我几个小时。 我似乎找不到这个问题的好答案。
我有各种各样的数字,我只需要保持到小数点后的第三位。 但是,如果右侧有尾随零,请将其删除。 例如:
0.015356 -> 0.015
0.015000 -> 0.015
0.010320 -> 0.01
0.000320 -> 0
我的数字是浮点数/双精度数。 我需要将它们传递给另一个 function 然后打印它们。 我无法控制其他 function。 我可以传递数字或字符串,它们会被相应地打印出来。
我想我需要传递一个字符串,否则无法实现?
我能够删除数字直到第三个:
num = floor(num*1000)/1000;
0.015356 -> 0.015000
0.000320 -> 0.000000
但是现在我遇到了尾随零的问题。
简而言之,我怎样才能实现我所需要的?
像这样的东西是你所追求的吗?
#include <iostream>
#include <sstream>
#include <iomanip>
#include <string>
#include <math.h>
std::string To_String_With_Decimal_Precision( double value, int decimals )
{
std::ostringstream ss;
ss << std::fixed << std::setprecision(decimals) << value;
std::string s = ss.str();
if(decimals > 0 && s[s.find_last_not_of('0')] == '.') {
s.erase(s.size() - decimals + 1);
}
return s;
}
int main()
{
double number = 0.015356;
//Round to 3d.p
number = floor(number*1000)/1000;
std::cout << number << std::endl;
std::cout << To_String_With_Decimal_Precision(number, 3);
return 0;
}
Output:
0.015
0.015
老实说,我不确定为什么number = floor(number*1000)/1000;
使数字等于 0.015 没有尾随零,但是如果在编译代码时该行不起作用,请使用To_String_With_Decimal_Precision
它应该适用于任何级别的小数精度
一个例程如何确定精度值,然后可以在 setprecision 中使用:这是一种设计,但由于它在本机浮点数上运行,精度错误比比皆是。 尝试使用输入 0.011 的不带括号的注释代码开始了解原因。 对于更健壮的东西,请考虑设计一种类似于此的替代算法来解析字符串并处理组件; 或者,使用多精度库。
// a truthy zerotest indicates that there is a zero at the place of interest
// inputs process outputs
// value represent as mega value precision up to
// zerotest thousandths
// [t]prec=2 "don't want zero 3 decimals
// zerotest hundredths
// [t]prec=1
// zerotest tenths
// [t]prec=0
std::streamsize // setprecision takes a std::streamsize, prob aliased to long long
precision_cutoff_at_zero_for(double const input)
{
int const inputMega = input *1000; // cast to int to discard decimals beyond 3
// WARNING float arithmetic e.g. input * 1000 is bad bad bad
// alt = input * (10.0*10.0*10.0) works but easy to forget parentheses losing precision
int precisionRelative = 3; // assume not evenly divisible by 10 (first case)
if (inputMega % 10 == 0) // evenly divisible by 10 (zerotest thousandth place)
{
--precisionRelative;
if (inputMega % 100 == 0) // 0 at far right, followed by another to the left?
{
--precisionRelative;
if (inputMega % 1000 == 0)
{
--precisionRelative; // etc
}
}
}
return precisionRelative;
}
然后从主要
// the number is stored in valueDouble and the case specific precision is returned from the routine defined above
std::cout << std::fixed << std::setprecision(precision_cutoff_at_zero_for(valueDouble)) << valueDouble << "\n";
如果您无法控制 function,那么您可能无法控制用于 output 的 stream。 如果是这种情况,那么正确的方法是将数字作为字符串传递并自行生成字符串。 一个简单的版本可以按如下方式工作:
#include <sstream>
int main() {
double f = 0.015356;
std::stringstream result;
result << "0.";
for (int mask = 10; mask <= 1000; mask*=10) {
int digit = ((int)(f * mask))%10;
result << digit;
}
std::cout << result.str();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.