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

veh*_*zzz 8 c c++ largenumber

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

现在我用

printf ("%10ld", number);
Run Code Online (Sandbox Code Playgroud)

格式

我会很感激使用printf得到的数字.我的大部分代码都是c ++,但我不想引入std :: cout,因为我已经有了printf

谢谢

pmg*_*pmg 12

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

根据我的文档,该'标志自1997年起可用于POSIX系统.

如果您使用的是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;
}
Run Code Online (Sandbox Code Playgroud)

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

# %'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
Run Code Online (Sandbox Code Playgroud)

  • 我希望这是标准的. (2认同)

Dig*_*oss 9

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

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 <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);
Run Code Online (Sandbox Code Playgroud)

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

       Suffix    Description    Multiplier
       k         kilo           1024
       M         mega           1048576
       G         giga           1073741824
       T         tera           1099511627776
       P         peta           1125899906842624
       E         exa            1152921504606846976
Run Code Online (Sandbox Code Playgroud)

  • 一个非常小的狡辩:"前缀"在事物之前(这就是"预先"意味着)."后缀"追求事物.110K使用K后缀表示110,000. (2认同)
  • 我真的很喜欢"非人化"功能名称:) (2认同)

Dan*_*ham 7

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

double n = (double)number;
printf("%10.0e", n);
Run Code Online (Sandbox Code Playgroud)


Pat*_*ick 6

std::cout << std::setprecision(5) << std::scientific << 100363443.0;
Run Code Online (Sandbox Code Playgroud)

请注意,该数字是浮点数

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

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;
Run Code Online (Sandbox Code Playgroud)

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

std::cout.imbue( std::locale( "" ) );
std::cout << 100363443 << std::endl;
Run Code Online (Sandbox Code Playgroud)