在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 }