2012-03-06 39 views
3

我應該使用什麼格式字符串printfiomanip運營商的iostream打印漂浮在以下格式:如何printf或者iostream的後點指定的最大位數

  • 125.0 => 125
  • 125.1 => 125.1
  • 125.12312 => 125.12
  • 1.12345 => 1.12
  • 1234.1235 => 1234.12

總之,打印點後最多2位數,但刪除所有尾隨零。

我試過%.2f但不起作用,因爲它打印前兩種情況下的125.00和125.10。

+3

只能設置絕對精度IIRC,而不是最高的精度。它是'std :: setprecision(...)'iostreams btw。 – Xeo 2012-03-06 17:17:10

+0

@Xeo,那麼有沒有簡單的解決辦法,如果我不堅持printf或iomanip?我不想處理該字符串,並自己刪除尾部零。 – 2012-03-06 18:36:27

回答

1

貌似我各地想出一些簡單的工作:

void print(float f) { 
    f = floor(f * 100.0f + 0.5f)/100.0f; 
    cout << f; 
} 

將解決最常見的情況。有一件事不能解決的是f> 10e7,這個cout將以科學概念打印f。

+0

你也可以使用'iostream'和'fixed'和'stringstream'打印到一個字符串,然後使用字符串操作來刪除尾隨零。然後打印最終的字符串。這將是低效的,但它會做你想做的。 – rob05c 2012-03-06 20:55:18

+0

我也是這樣做的,我覺得在C++中沒有什麼比這更簡單了。順便說一下,我發現135.545的數字不會被四捨五入爲135.55而是135.54,而當您嘗試使用另一個數字時,例如125.545將被四捨五入爲125.55而不是125.54。如果有人知道爲什麼,告訴我,這與C++無關,尤其是因爲JavaScript中發生的情況;)可以嘗試:console.log(Math.round(135.545 * 100)/ 100); – baptx 2013-03-02 21:08:26

+1

@baptx,我認爲這與如何在計算機中表示浮點數有關。我認爲在計算機中,像0.1這樣的數字不能用二進制數來精確表示。例如,1/3 = 0.33333 ....不能用十進制精確表示,因爲3不是2和5的乘法(10 = 2 * 5)。在二進制表示中1/10也是如此,因爲5不是2的冪。因此,您觀察到的問題可能是因爲135.545在計算機中可能是135.54500001,125.545是125.54499999 – 2013-03-05 16:46:38

1

這是iostream的默認浮點行爲。只需將精度設置爲最大位數(在您的示例中爲5),並正常輸出到流。

+0

他想要設置小數位後的最大位數,而不是最大位數。 – 2012-03-06 18:14:03

+0

@VaughnCato我不知道他真的想看到什麼。他不說;他只提供了幾個例子。我想清楚的是,他不希望在小數點後面有任何尾隨的'0',並且如果之前有3個數字,他不希望超過2位數字:是否意味着總共5位數,或小數點後2位,我不知道。 – 2012-03-06 18:35:27

+0

@JamesKanze,我確實說過「簡而言之,在點後最多打印2位數字,但刪除所有尾部零。」當我最初發布這個。我後面只添加了一些例子。 – 2012-03-06 18:50:54

2

iostream使用flags

具體而言,請使用std::cout << std::setprecision(5)將精度設置爲5.請參閱setprecisionios_base::precision

如果您設置了精度,但沒有設置fixed,它將使用您指定的精度而不用尾隨零。如果您還設置了fixed標誌,它將打印尾隨零直到您指定的精度。

printf也使用自己的標誌。有關如何使用它,請參見the documentation

+0

你可以顯示我舉一些例子?我試過使用它,但不起作用。 – 2012-03-06 17:27:22

+0

沒有最大限度,我們經常使用'17'(如果你想確保往返旅行,這是必需的)。 – 2012-03-06 17:27:48

+0

@icando'double almostpi = 3.1415926535897932384; std :: cout << std :: setprecision(6); std :: cout << almostpi;'應該打印'3.14159'。 – rob05c 2012-03-06 17:33:26

0

printf家族爲此目的具有%g格式(但在某些情況下,它還有另一個目的是在%e中更改%f)。正如James指出的那樣,這是C++ IOStream的默認行爲;如果它已被更改爲其他重置密碼:

#include <iostream> 
#include <iomanip> 
#include <stdio.h> 

int main() 
{ 
    printf("%.2g %.2g\n", 1.2, 0.0000012); 
    std::cout << std::fixed << std::setprecision(2) << 1.2 << " " << 0.0000012 << '\n'; 
    std::cout.setf(std::ios_base::fixed|std::ios_base::scientific, std::ios_base::floatfield); 
    std::cout << std::setprecision(2) << 1.2 << " " << 0.0000012 << '\n'; 
} 

1.2 1.2e-06 
1.20 0.00 
1.2 1.2e-06 
+0

你能告訴我一些例子嗎?我試過使用它,但不起作用。 – 2012-03-06 17:28:13

+0

%.2g不符合我的需求。 125打印爲1.2e + 02 – 2012-03-06 18:28:04

1

有沒有辦法來指定。您可以指定小數位後的精確位數(以便它在需要時添加零)或最大有效位數,但不是小數位後的最大位數。

注意:Xeo在評論中首先回答了這個問題。

+0

因此,如果我不堅持使用printf或iomanip,還有其他解決方法嗎? – 2012-03-06 18:34:33

0

試試這個:

char buf[5]; 
int l = snprintf(buf, sizeof buf, "%.2f", x); 
if (!strcmp(buf, "0.00")) printf("0\n"); 
else printf("%.*g\n", l-1, x); 
相關問題