在源代码中代表大数字以提高可读性?
是否有更人性化的方式来表示用C ++或C编写的应用程序的源代码中的大数字?
例如,如果我们想要一个程序返回这个数字我们会return 2345879444641
,请使用C或C ++中的数字return 2345879444641
。
但这不是真的可读。
例如,在PAWN(脚本语言)中,我可以return 2_345_879_444_641
或甚至return 2_34_58_79_44_46_41
,这两者都将返回数字2,345,879,444,641
。
对于人眼来说,这更具可读性。
这有C或C ++的等价物吗?
这是一个可以在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;
使用当前编译器(C ++ 14或更高版本),您可以使用撇号,如:
auto a = 1'234'567;
如果您仍然坚持使用C ++ 11,则可以使用用户定义的文字来支持以下内容: int i = "1_000_000"_i
。 代码看起来像这样:
#include #include #include 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
。
当然,欧洲人可能更喜欢“。” 而不是“,” - 如果是这样,请随意修改,如你所愿。
使用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。 留作练习(也因为它需要更多代码)。
对于C ++ 1y,您现在可以使用单引号( '
)作为数字分隔符。 基于N3781:单引号标记作为数字分隔符 , 最终被接受 。 作为C ++ 1y实现的一部分, gcc和clang都支持此function。
所以下面的程序( 看到它为clang直播 ):
#include int main(){ std::cout << 2'345'879'444'641 << std::endl ; }
将输出:
2345879444641
您可以使用预处理器宏
#define BILLION (1000*1000*1000)
然后编码例如(4*BILLION)
; 如果你关心的是2的大功率只是1<<30
PS注意1e6
是double
字面(与1.0e6
相同)
你也可以:
- 修补GCC词法分析器以接受数字文字的
1_234_567
表示法,并发布该补丁以符合GPLv3和自由软件精神。
可能在未来GCC 4.8的文件libpp/lex.c
和/或gcc/c-family/c-lex.c
和/或gcc/cpp/lex.c
中,即当前主干。 - 游说C&C ++标准化小组,以便在未来的C或C ++标准中得到认可。