繁体   English   中英

删除十进制 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM