我的程序打印出非常大的数字,比如100363443,甚至高达一万亿,这样的数字有些难以阅读,因此我希望能够以易于阅读的形式打印任何数字。
目前我使用的方法是:
printf ("%10ld", number);
格式化
我希望使用printf函数得到一个结果数字。我的大部分代码是用C++编写的,但我不想引入std::cout,因为我已经在使用printf函数了。
谢谢
我的程序打印出非常大的数字,比如100363443,甚至高达一万亿,这样的数字有些难以阅读,因此我希望能够以易于阅读的形式打印任何数字。
目前我使用的方法是:
printf ("%10ld", number);
格式化
我希望使用printf函数得到一个结果数字。我的大部分代码是用C++编写的,但我不想引入std::cout,因为我已经在使用printf函数了。
谢谢
如果你有这个选项并且不介意失去一些可移植性,可以在printf格式字符串中使用非标准的apostrophe
标志。
根据我的文档,在POSIX系统自1997年以来就已经支持'
标志。
如果你在Unix、Linux、Mac等系统上,应该没有问题。
但如果你在Windows、DOS、iSeries、Android等系统上,则无法保证(但也许可以在系统上安装一个POSIX层)。
#include <locale.h>
#include <stdio.h>
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(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 <stdlib.h>
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
简单的方法可能是在输出前将其转换为double,然后使用%e,它将以指数科学计数法打印。试试这个:
double n = (double)number;
printf("%10.0e", n);
std::cout << std::setprecision(5) << std::scientific << 100363443.0;
struct comma : public std::numpunct<char>
{
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。
这是我用纯C编写的一个示例,没有使用locale。仅适用于正数。(得到了“DiscoVlad”的很多帮助)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <strings.h>
void my_reverse ( char* s ) {
int c, i, j;
for (i=0, j= strlen(s)-1;i<j;i++,j--) {
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
char* insert_commas(unsigned long long input ) {
int i, intlen;
char* buffer;
char* formatted;
intlen = (int) ceil(log10(input * 1.0));
buffer = (char *) malloc((intlen + 1) * sizeof(char));
sprintf(buffer, "%llu", input); // build buffer
formatted = (char *) malloc((intlen + (int) ceil(intlen/3.0)) * sizeof(char)); // malloc output buffer
my_reverse(buffer);
for(i=intlen; i>=0; i--) {
formatted[strlen(formatted)] = buffer[i];
if (i%3 == 0 && i<intlen && 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
}