Представление больших чисел в исходном коде для удобочитаемости?
Есть ли более человечно читаемый способ представления больших чисел в исходном коде приложения, написанного на С++ или 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