¿Representando números grandes en el código fuente para la legibilidad?

¿Hay alguna forma más legible para los humanos para representar números grandes en el código fuente de una aplicación escrita en C ++ o C?

2,345,879,444,641 , por ejemplo, el número 2,345,879,444,641 , en C o C ++ si quisiéramos que un progtwig devolviera este número, lo haríamos return 2345879444641 .

Pero esto no es realmente legible.

En PAWN (un lenguaje de scripting), por ejemplo, puedo return 2_345_879_444_641 o incluso return 2_34_58_79_44_46_41 y estos dos devolverán el número 2,345,879,444,641 .

Esto es mucho más legible para el ojo humano.

¿Hay un equivalente en C o C ++ para esto?

Aquí hay una macro que lo haría, probada tanto en MSVC como en GCC. No confiar en 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_ 

Úselo como:

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

Produce:

 int y = 12345678; int x = 100460694; 

Con un comstackdor actual (C ++ 14 o posterior), puede usar apóstrofes, como:

 auto a = 1'234'567; 

Si todavía está atrapado con C ++ 11, podría usar un literal definido por el usuario para soportar algo como: int i = "1_000_000"_i . El código se vería así:

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

Tal como lo escribí, esto admite guiones bajos o comas indistintamente, por lo que podría usar uno u otro, o ambos. Por ejemplo, "1,000_000" resultaría como 1000000 .

Por supuesto, los europeos probablemente preferirían "." en lugar de "," - si es así, siéntase libre de modificar como mejor le parezca.

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

Uso:

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

Demo

Otra forma es hacer un UDL. Se deja como ejercicio (y también porque requiere más código).

Para C ++ 1y , ahora puede usar comillas simples ( ' ) como un separador de dígitos. Basado en N3781: Single-Quotation-Mark como un separador de dígitos que finalmente ha sido aceptado . Tanto gcc como clang han admitido esta característica como parte de su implementación de C ++ 1y .

Así que el siguiente progtwig ( verlo en vivo para clang ):

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

dará salida:

2345879444641

Podría usar una macro de preprocesador

  #define BILLION (1000*1000*1000) 

luego codifique, por ejemplo, (4*BILLION) ; si te importa una gran potencia de dos solo ust 1<<30

PD Observe que 1e6 es un double literal (igual que 1.0e6 )

Y también podrías:

  1. 1_234_567 GCC para aceptar la notación 1_234_567 para literales numéricos y publique ese parche para cumplir con GPLv3 y espíritu de software libre.
    probablemente en el archivo libpp/lex.c y / o gcc/c-family/c-lex.c y / o gcc/cpp/lex.c del futuro GCC 4.8, es decir, el tronco actual.
  2. presionar a los grupos de estandarización de C & C ++ para que sean aceptados en futuros estándares C o C ++.