在C / C ++中将天文数字大数字转换为人类可读forms

我的程序打印出巨大的数字 – 比如100363443,高达万亿 – 而且很难阅读它们,所以我想以易于阅读的forms打印任何数字。

现在我用

printf ("%10ld", number); 

格式

我很感激使用printf生成的数字。 我的大多数代码都是c ++但我不想引入std :: cout,因为我已经有了printf

谢谢

如果您有该选项可用,请使用printf格式字符串中的非标准apostrophe标记,并且不介意丢失一点可移植性。

根据我的文档,自1997年以来, '标志可用于POSIX系统。

如果你在Unix,Linux,Mac上……你应该没问题
如果你在Windows,DOS,iSeries,Android,…所有的赌注都关闭(但也许你可以在你的系统中安装POSIX层)。

 #include  #include  int main(void) { long int x = 130006714000000; setlocale(LC_NUMERIC, "en_US.utf-8"); /* important */ while (x > 0) { printf("# %%'22ld: %'22ld\n", x); /* apostrophe flag */ x *= 2; /* on my machine, the Undefined Behaviour for overflow // makes the number become negative with no ill effects */ } return 0; } 

在我的系统上,该程序产生:

 # %'22ld: 130,006,714,000,000 # %'22ld: 260,013,428,000,000 # %'22ld: 520,026,856,000,000 # %'22ld: 1,040,053,712,000,000 # %'22ld: 2,080,107,424,000,000 # %'22ld: 4,160,214,848,000,000 # %'22ld: 8,320,429,696,000,000 # %'22ld: 16,640,859,392,000,000 # %'22ld: 33,281,718,784,000,000 # %'22ld: 66,563,437,568,000,000 # %'22ld: 133,126,875,136,000,000 # %'22ld: 266,253,750,272,000,000 # %'22ld: 532,507,500,544,000,000 # %'22ld: 1,065,015,001,088,000,000 # %'22ld: 2,130,030,002,176,000,000 # %'22ld: 4,260,060,004,352,000,000 # %'22ld: 8,520,120,008,704,000,000 

您可以使用humanize_number(),它使用k,m等后缀来省略低位数字。 这不是标准例程,因此您应该删除我链接的源代码。 (2条款BSD许可,允许任何forms的使用。)

Humanize_number手册页 。

来自NetBSD的 Humanize_number源代码 。

 HUMANIZE_NUMBER(3) NetBSD Library Functions Manual HUMANIZE_NUMBER(3) NAME dehumanize_number, humanize_number -- format a number into a human read- able form and viceversa SYNOPSIS #include  int dehumanize_number(const char *str, int64_t *result); int humanize_number(char *buf, size_t len, int64_t number, const char *suffix, int scale, int flags); 

这通过附加后缀来实现,如下所示:

  Suffix Description Multiplier k kilo 1024 M mega 1048576 G giga 1073741824 T tera 1099511627776 P peta 1125899906842624 E exa 1152921504606846976 

简单的方法可能是在输出之前转换为双精度并使用%e,它将以指数科学记数法打印它们。 试试这个:

 double n = (double)number; printf("%10.0e", n); 
 std::cout << std::setprecision(5) << std::scientific << 100363443.0; 

请注意,该数字是浮点数

编辑:或者如果你不喜欢科学我在网上发现了这个:

 struct comma : public std::numpunct { protected: std::string do_grouping() const { return "\003" ; } }; std::cout.imbue( std::locale( std::cout.getloc(), new comma ) ); std::cout << 100363443 << std::endl; 

编辑2:正如Jerry所指出的那样,你不需要上面的逗号类,这本身就足够了(虽然有些区域可能根本没有格式化大数字?):

 std::cout.imbue( std::locale( "" ) ); std::cout << 100363443 << std::endl; 

记住本地化(特别是如果你正在编写一个库)。
在欧洲(英国除外),它将是1.000.000而不是1,000,000

这是我使用locale直接用C编写的一个例子。 只适用于积极因素。 (“DiscoVlad”的帮助很多)

 #include  #include  #include  #include  void my_reverse ( char* s ) { int c, i, j; for (i=0, j= strlen(s)-1;i=0; i--) { formatted[strlen(formatted)] = buffer[i]; if (i%3 == 0 && i 0) { formatted[strlen(formatted)] = ','; } } free(buffer); return formatted; } int main() { char* formatted; // don't forget to free(formatted) after each call. formatted = insert_commas(123); printf("output %s\n", formatted); // output 123 formatted = insert_commas(1234); printf("output %s\n", formatted); // output 1,234 formatted = insert_commas(123456); printf("output %s\n", formatted); // output 123,456 formatted = insert_commas(1234567); printf("output %s\n", formatted); // output 1,234,567 formatted = insert_commas(123456789); printf("output %s\n", formatted); // output 123,456,789 formatted = insert_commas(12345678901234567890ull); printf("output %s\n", formatted); // output 12,345,678,901,234,567,890 }