Representing big numbers in source code for readability?

后端 未结 5 2082
难免孤独
难免孤独 2020-11-27 23:23

Is there a more human-readable way for representing big numbers in the source code of an application written in C++ or C?

let\'s for example take the number 2,

相关标签:
5条回答
  • 2020-11-27 23:57

    Here's a macro that would do it, tested on both MSVC and GCC. No reliance on 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_
    

    Use it like:

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

    Produces:

    int y = 12345678;
    int x = 100460694;
    
    0 讨论(0)
  • 2020-11-28 00:04

    For C++1y you can now use single quote(') as a digit separator. Based on N3781: Single-Quotation-Mark as a Digit Separator which has finally been accepted. Both gcc and clang have supported this feature as part of their C++1y implementation.

    So the following program (see it live for clang):

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

    will output:

    2345879444641

    0 讨论(0)
  • 2020-11-28 00:05

    You could use a preprocessor macro

      #define BILLION (1000*1000*1000)
    

    then code e.g. (4*BILLION) ; if you care about large power of two just ust 1<<30

    PS Notice that 1e6 is a double literal (same as 1.0e6)

    And you could also:

    1. patch the GCC lexer to accept 1_234_567 notation for number literals and publish that patch for conformance with GPLv3 and free software spirit.
      probably in file libpp/lex.c and/or gcc/c-family/c-lex.c and/or gcc/cpp/lex.c of future GCC 4.8, i.e. current trunk.
    2. lobby the C & C++ standardization groups to get that accepted in future C or C++ standards.
    0 讨论(0)
  • 2020-11-28 00:10

    With a current compiler (C++14 or newer), you can use apostrophes, like:

    auto a = 1'234'567;
    

    If you're still stuck with C++11, you could use a user-defined literal to support something like: int i = "1_000_000"_i. The code would look something like this:

    #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;
    }
    

    As I've written it, this supports underscores or commas interchangeably, so you could use one or the other, or both. For example, "1,000_000" would turn out as 1000000.

    Of course, Europeans would probably prefer "." instead of "," -- if so, feel free to modify as you see fit.

    0 讨论(0)
  • 2020-11-28 00:12

    With 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)
    

    Usage:

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

    Demo.

    Another way is making an UDL. Left as an exercise (and also because it requires more code).

    0 讨论(0)
提交回复
热议问题