Представление больших чисел в исходном коде для удобочитаемости?

Есть ли более человечно читаемый способ представления больших чисел в исходном коде приложения, написанного на С++ или C?

пусть, например, возьмем число 2,345,879,444,641, в C или С++, если мы хотим, чтобы программа возвращала это число, мы сделали бы return 2345879444641.

Но это не совсем понятно.

В PAWN (язык сценариев), например, я могу сделать return 2_345_879_444_641 или даже return 2_34_58_79_44_46_41, и оба они вернут номер 2,345,879,444,641.

Это гораздо более читаемо для человеческого глаза.

Есть ли для этого эквивалент C или С++?

Ответ 1

Вот макрос, который бы это сделал, протестированный как на 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;

Ответ 2

С текущим компилятором (С++ 14 или новее) вы можете использовать апострофы, например:

auto a = 1'234'567;

Если вы все еще придерживаетесь С++ 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;
}

Как я уже писал, это означает, что символы подчеркивания или запятые взаимозаменяемы, поэтому вы можете использовать один или другой или оба. Например, "1000_000" получится как 1000000.

Конечно, европейцы, вероятно, предпочли бы "." вместо "," - если это так, не стесняйтесь изменять, как вы сочтете нужным.

Ответ 3

С 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. Оставленный как упражнение (а также потому, что он требует больше кода).

Ответ 4

Вы можете использовать макрос препроцессора

  #define BILLION (1000*1000*1000)

затем код, например. (4*BILLION); если вы заботитесь о большой мощности двух просто ust 1<<30

PS Обратите внимание, что 1e6 является литералом double (таким же, как 1.0e6)

И вы также можете:

  • исправить лексику GCC, чтобы принять обозначение 1_234_567 для числовых литералов и опубликовать этот патч для соответствия GPLv3 и духу свободного программного обеспечения.
    возможно в файле libpp/lex.c и/или gcc/c-family/c-lex.c и/или gcc/cpp/lex.c будущего GCC 4.8, то есть текущей магистрали.
  • лоббировать группы стандартизации C и С++, чтобы получить это в будущих стандартах C или С++.

Ответ 5

Для С++ 1y вы можете использовать одиночную кавычку (') в качестве разделителя цифр. На основе N3781: Одиночный комментарий как разделитель цифр, который наконец были приняты. Оба gcc и clang поддерживают эту функцию как часть их реализации С++ 1y.

Итак, следующая программа (видеть ее вживую для clang):

#include <iostream>

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

выведет:

2345879444641