[英]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.