25

在用 C++ 或 C 编写的应用程序的源代码中,是否有一种更易读的方式来表示大数字?

让我们以数字为例2,345,879,444,641,在 C 或 C++ 中,如果我们想要一个程序返回这个数字,我们会这样做return 2345879444641

但这不是真正可读的。

例如,在 PAWN(一种脚本语言)中,我可以做return 2_345_879_444_641,甚至return 2_34_58_79_44_46_41这些都将返回 number 2,345,879,444,641

这对于人眼来说更具可读性。

是否有 C 或 C++ 等价物?

4

5 回答 5

32

使用当前编译器(C++14 或更高版本),您可以使用撇号,例如:

auto a = 1'234'567;

如果您仍然坚持使用 C++11,您可以使用用户定义的文字来支持类似的内容:int i = "1_000_000"_i. 代码看起来像这样:

#include <iostream>
#include <string>
#include <cstdlib>

int operator "" _i (char const *in, size_t len) { 
    std::string input(in, len);
    int pos;

    while (std::string::npos != (pos=input.find_first_of("_,"))) 
        input.erase(pos, 1);

    return std::strtol(input.c_str(), NULL, 10);
}

int main() { 
    std::cout << "1_000_000_000"_i;
}

正如我所写的那样,它支持下划线或逗号互换,因此您可以使用其中一个或两个,或两者兼而有之。例如,“1,000_000”会变成1000000.

当然,欧洲人可能更喜欢“.”。而不是“,”——如果是这样,请随意修改您认为合适的内容。

于 2013-01-08T17:36:05.853 回答
12

使用Boost.PP

#define NUM(...) \
    NUM_SEQ(BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) 
#define NUM_SEQ(seq) \
    BOOST_PP_SEQ_FOLD_LEFT(NUM_FOLD, BOOST_PP_SEQ_HEAD(seq), BOOST_PP_SEQ_TAIL(seq)) 
#define NUM_FOLD(_, acc, x) \
    BOOST_PP_CAT(acc, x)

用法:

NUM(123, 456, 789) // Expands to 123456789

演示

另一种方法是制作 UDL。留作练习(也因为它需要更多代码)。

于 2013-01-08T17:10:33.743 回答
7

这是一个可以做到这一点的宏,在 MSVC 和 GCC 上都经过测试。不依赖 Boost...

#define NUM(...) NUM_(__VA_ARGS__, , , , , , , , , , )
#define NUM_(...) NUM_MSVCHACK((__VA_ARGS__))
#define NUM_MSVCHACK(numlist_) NUM__ numlist_
#define NUM__(a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, ...) a1_##a2_##a3_##a4_##a5_##a6_##a7_##a8_

像这样使用它:

int y = NUM(1,2,3,4,5,6,7,8);
int x = NUM(100,460,694);

产生:

int y = 12345678;
int x = 100460694;
于 2013-01-08T17:36:23.387 回答
4

对于C++1y,您现在可以使用单引号 ( ') 作为数字分隔符。基于N3781:单引号作为数字分隔符最终被接受gccclang都支持此功能作为其C++1y实现的一部分。

所以下面的程序(看到它现场为铿锵):

#include <iostream>

int main(){
    std::cout << 2'345'879'444'641 << std::endl ;
}

将输出:

2345879444641

于 2014-02-18T03:35:06.740 回答
3

您可以使用预处理器宏

  #define BILLION (1000*1000*1000)

然后编码例如(4*BILLION);如果你关心两个的大功率只是 ust1<<30

PS 注意这1e6是一个double文字(与 相同1.0e6

您还可以:

  1. 修补 GCC 词法分析器以接受1_234_567数字文字的符号并发布该补丁以符合 GPLv3 和自由软件精神。
    可能在文件libpp/lex.c和/或gcc/c-family/c-lex.c和/或gcc/cpp/lex.c未来的 GCC 4.8 中,即当前的主干。
  2. 游说 C 和 C++ 标准化组织,以使其在未来的 C 或 C++ 标准中被接受。
于 2013-01-08T17:03:31.603 回答