簡體   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