Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: meoit ARG en 28 Abril 2014, 21:56 pm



Título: Problema en variable int
Publicado por: meoit ARG en 28 Abril 2014, 21:56 pm
Hola gente :)

mi problema es que tengo una variable llamada numero, que su valor es dado por el usuario, y con ese numero trabaja el programa que estoy haciendo

Código
  1. if ((numero > 99999999999999999999) && (numero < 10000000000000000)) //si numero tiene 21 caracteres
  2. {
  3. }

el problema es que  99999999999999999999 es un valor que execede la capacidad de bits de la variable int, pero la cambio a long double y sigue ese error...

Espero que me hayan entendido

Salu2 meoit =)


Título: Re: Problema en variable int
Publicado por: vangodp en 28 Abril 2014, 22:02 pm
18446744073709551615   <= unsigned long long int  :laugh:
99999999999999999999
pues ni idea amigo jajaj me has vencido hasta a mi XDD


Título: Re: Problema en variable int
Publicado por: xv0 en 28 Abril 2014, 22:18 pm
Es un numero de 64 bits "quad", prueba con un long long int.

Un saludo.


Título: Re: Problema en variable int
Publicado por: leosansan en 28 Abril 2014, 23:06 pm
Hola gente :)
.................................

Código
  1. if ((numero > 99999999999999999999) && (numero < 10000000000000000)) //si numero tiene 21 caracteres
  2. {
  3. }

............................................

Salu2 meoit =)

Antes que nada revisa esas condiciones ya que no puede ser a la vez:

Código
  1. numero>99999999999999999999  y
  2. numero<10000000000000000

¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Problema en variable int
Publicado por: meoit ARG en 29 Abril 2014, 03:15 am
Antes que nada mil gracias por sus respuestas a todos.
 Cpu2 cuando este en mi ordenador lo probaré
Loesansan: estaba trabajando con el codigo, no llegue a editar esa condicion porque la primera me tiraba error, igual se entiende mi problema xD
Vangodp: jajaja ya somos dos :DD


Título: Re: Problema en variable int
Publicado por: vangodp en 29 Abril 2014, 09:18 am
Bueno compañero, por donde busques eso es tema de silencio jeje secretismo XDDD
Solo opinan los gatos como yo ¿pero que vamos hacer? Venga vamos allá =D
A noche investigando por internet he encontrado 2 soluciones.
Una es que añadas librerías externas y otra que lo reinventes vos la rueda ><
Pues en vez de guardar números en enteros que los guardes en strings luego a la hora de sumar te quemas el coco haciendo como si lo hiciera en papel, por ejemplo si tienes un numero: XD
091278q358172345324785983247572340985723477239047592389045
pues lo guardas en string

string n = "091278q358172345324785983247572340985723477239047592389045";

hasta aquí no has reinventado nada XDD
venga vamos a ver como lo hacemos...
si tenemos 2 cadenas de numeros
091278q358172345324785983247572340985723477239047592389045
091278q358172345324785983247572340985723477239047592389045

como se sumaria eso en papel???

empezariamos por el ultimo numero 5 ¿verdad?...¡No te la voy hacer hombre! Eso lo haces tu XDD

pues bien... "cualquier operación que realicemos en papel se puede realizar en las tablas", lo pongo entre "" por que la frase no es mía XDD

La cosa seria sumar el 5 de arriba que seria el ultimo numero de una tabla con el siguiente que es otra tabla.
Los tomas como string o como una tabla fija de números al que declaras antes, o puedes hacer uso del heap ;)
si sumas por ejemplo 6 + 6 ya ves que tenemos un problema y es que da 12, ese 1 tienes que sumar a la casilla previa. Pero no todo el monte es orgasmo, las funciones de comparación las tendrías que hacer tu también, al igual que la de resta y las demás operaciones, también lo tendrías que hacer para los flotantes en caso de necesitar. Acabarías por escribir una librería completa XDDD

Una solución también seria usar notación científica para encoger esos números pero seria lo mismo por que hay símbolos y no los puedes meter en un entero. =(

Bueno...no tenemos por que reinventar la rueda.
He encontrado 2 librerías que hacen eso.Pero debo de señalar que desconozco ambas, por que nunca use esos números tan largos, simplemente es un tema que me interesa por si las moscas un dia....

Bien segun "he leido" y encontre :
http://www.ginac.de/CLN/cln.html
https://mattmccutchen.net/bigint/index.html

la primera la encontre en un tema que esta aqui: http://clan-destino42.blogspot.com.es/2011/01/numeros-grandes-en-c.html

Según el bloguero la CLN trabaja el y puede usar numeros de 300 caracteres.
La otra me parece que puede con 200 caracteres.

Pero la cosa no son la cantidad de caracteres sino la cantidad de funciones que tenga dicha librería, cosas como comparar, restar o lo que sea y si posible no nos cambia la forma de trabajar que tenemos pues seria genial :D

Ahora toca buscar a ver si valen para algo =D
Lo siento no poder ayudar mas, pero no soy ni científico friky XDD ni un programador avanzado, puede que aya mejores opciones por Internet y solo hay que investigar un poco mas.
Es que no es muy normal que digamos usar esos tipos de números en programación normal y corriente, por eso pocos contestan.

Suerte!

Si encuentras algo mejor comparte aquí que también me interesa saber algo =D  ;-)






Título: Re: Problema en variable int
Publicado por: eferion en 29 Abril 2014, 10:14 am
¿Y hacerte una clase para manejar números grandes?

También puedes aprovechar alguna clase ya existente en internet para realizar esta tarea.

Si estás programando en C el tema de las clases ya no te sirve... pero aún así sigue habiendo opciones.


Título: Re: Problema en variable int
Publicado por: vangodp en 29 Abril 2014, 11:23 am
po funciones ¿eso es lo que puedes aportar al tema? Señalar los fallos? Si no lo sabe un programador como tu nada que ayude estamos perdidos :silbar:
 :laugh:


Título: Re: Problema en variable int
Publicado por: eferion en 29 Abril 2014, 11:41 am
Código
  1. #include <bitset>
  2. #include <iostream>
  3. #include <string>
  4. #include <vector>
  5.  
  6. class BigNum
  7. {
  8.  public:
  9.  
  10.    BigNum( int number = 0 );
  11.  
  12.    BigNum( const std::string& number );
  13.  
  14.    BigNum operator+( const BigNum& number );
  15.  
  16.    std::string ToBinString( ) const;
  17.  
  18.    std::string ToString( ) const;
  19.  
  20.  private:
  21.  
  22.    bool _negative;
  23.    std::vector< unsigned int > _number;
  24.  
  25.    void Mul10AddN( unsigned int number );
  26.  
  27.    std::string Mul2( const std::string& number ) const;
  28.  
  29.    std::string Mul2AddN( const std::string& number, int carry ) const;
  30.  
  31.    void FromString( const std::string& number );
  32. };
  33.  
  34. BigNum::BigNum( int number )
  35.  : _negative( false )
  36. {
  37.  if ( number < 0 )
  38.  {
  39.    _negative = true;
  40.    number = -number;
  41.  }
  42.  else if ( number > 0 )
  43.    _number.push_back( number );
  44. }
  45.  
  46. BigNum::BigNum( const std::string& number )
  47. {
  48.  FromString( number );
  49. }
  50.  
  51. BigNum BigNum::operator +( const BigNum& number )
  52. {
  53. //  if ( number1._negative != number2._negative )
  54. //  {
  55. //    if ( number1._negative )
  56. //    {
  57. //      BigNum temp = number1;
  58. //      temp._negative = false;
  59. //      return number2 - temp;
  60. //    }
  61. //    else
  62. //    {
  63. //      BigNum temp = number2;
  64. //      temp._negative = false;
  65. //      return number1 - temp;
  66. //    }
  67. //  }
  68.  
  69.  BigNum to_return;
  70.  to_return._negative = _negative;
  71.  
  72.  unsigned int carry = 0;
  73.  unsigned int max = (_number.size( ) > number._number.size( ) )? _number.size( )
  74.                                                                : number._number.size( );
  75.  
  76.  for ( unsigned int i=0; i < max; i++ )
  77.  {
  78.    unsigned long long temp = 0;
  79.  
  80.    if ( i < _number.size( ) )
  81.      temp = static_cast< unsigned long long >( _number[ i ] );
  82.  
  83.    if ( i < number._number.size( ) )
  84.      temp += static_cast< unsigned long long >( number._number[ i ] );
  85.  
  86.    temp += carry;
  87.  
  88.    to_return._number.push_back( static_cast< unsigned int >(temp & 0xFFFFFFFF) );
  89.    carry = static_cast< unsigned int >(temp >> 32);
  90.  }
  91.  
  92.  if ( carry != 0 )
  93.    to_return._number.push_back( static_cast< unsigned int >( carry ) );
  94.  
  95.  return to_return;
  96. }
  97.  
  98. std::string BigNum::ToBinString( ) const
  99. {
  100.  std::string to_return;
  101.  
  102.  for ( unsigned int i=_number.size( ) - 1; i < _number.size( ); i-- )
  103.  {
  104.    std::bitset< 32 > bits( static_cast< int >( _number[ i ] ) );
  105.    to_return += bits.to_string( );
  106.  }
  107.  
  108.  while ( to_return[ 0 ] == '0' )
  109.    to_return.erase( to_return.begin( ) );
  110.  
  111.  int i = static_cast< int >( to_return.size( ) ) - 4;
  112.  while ( i > 0 )
  113.  {
  114.    to_return.insert( i, 1, ' ' );
  115.    i -= 4;
  116.  }
  117.  return to_return;
  118. }
  119.  
  120. std::string BigNum::ToString() const
  121. {
  122.  std::string to_return = "0";
  123.  
  124.  for ( auto it = _number.rbegin( ); it != _number.rend( ); ++it )
  125.  {
  126.    int data = *it;
  127.    for ( int i=0; i< 32; i++ )
  128.    {
  129.      to_return = Mul2AddN( to_return, (data & 0x80000000)? 1 : 0 );
  130.      data <<= 1;
  131.    }
  132.  }
  133.  
  134.  return to_return;
  135. }
  136.  
  137. void BigNum::Mul10AddN(unsigned int number)
  138. {
  139.  if ( _number.empty( ) )
  140.  {
  141.    _number.push_back( number );
  142.    return;
  143.  }
  144.  
  145.  unsigned long long carry = static_cast< unsigned long long >( number );
  146.  unsigned long long ten = 10;
  147.  for ( unsigned int i = 0; i < _number.size( ); i++ )
  148.  {
  149.    unsigned long long temp = static_cast< unsigned long long >( _number[ i ] ) * ten + carry;
  150.  
  151.    _number[ i ] = static_cast < unsigned int >( temp & 0xFFFFFFFF);
  152.    carry = ( temp >> 32 );
  153.  }
  154.  
  155.  if ( carry != 0 )
  156.    _number.push_back( static_cast< unsigned int >( carry ) );
  157. }
  158.  
  159. std::string BigNum::Mul2AddN(const std::string& number, int carry ) const
  160. {
  161.  std::string to_return;
  162.  
  163.  for ( auto it = number.rbegin( ); it != number.rend( ); ++it )
  164.  {
  165.    int temp = (*it - '0') * 2 + carry;
  166.  
  167.    if ( temp >= 10 )
  168.    {
  169.      temp -= 10;
  170.      carry = 1;
  171.    }
  172.    else
  173.      carry = 0;
  174.  
  175.    to_return.insert( 0, 1, temp + '0' );
  176.  }
  177.  
  178.  if ( carry != 0 )
  179.    to_return.insert( 0, 1, carry + '0' );
  180.  
  181.  return to_return;
  182. }
  183.  
  184. void BigNum::FromString(const std::string& number)
  185. {
  186.  unsigned int i=0;
  187.  if ( number[ i ] == '-' )
  188.  {
  189.    _negative = true;
  190.    i++;
  191.  }
  192.  else
  193.    _negative = false;
  194.  
  195.  _number.clear( );
  196.  
  197.  for ( ; i < number.length( ); i++ )
  198.  {
  199.    unsigned int digit = number[ i ] - 0x30;
  200.    Mul10AddN( digit );
  201.  }
  202. }
  203.  
  204. int main( )
  205. {
  206.  BigNum a( 100 );
  207.  BigNum b( "9000000000000" );
  208.  
  209.  BigNum c = a + b;
  210.  
  211.  std::cout << a.ToString( ) << std::endl
  212.            << "+" << std::endl
  213.            << b.ToString( ) << std::endl
  214.            << "=" << std::endl
  215.            << c.ToString( ) << std::endl;
  216.  
  217.  a = BigNum( "123456123456123456123456123456123123" );
  218.  b = BigNum( "876543211234567876543212345678");
  219.  c = a + b;
  220.  
  221.  
  222.  std::cout << a.ToString( ) << std::endl
  223.            << "+" << std::endl
  224.            << b.ToString( ) << std::endl
  225.            << "=" << std::endl
  226.            << c.ToString( ) << std::endl;
  227. }
  228.  

Como es de esperar... ni está optimizada ni completa... está hecha en un rato para satisfacer el insaciable apetito de vangodp... pero vale de ejemplo.

actualizado: Ahora también imprime el string en base 10.


Título: Re: Problema en variable int
Publicado por: vangodp en 29 Abril 2014, 14:10 pm
no me equivocaba jeje Si no lo sabes tu quien va saberlo ^^
Ahora me falta un mes para analizar el código  :laugh:


Título: Re: Problema en variable int
Publicado por: eferion en 29 Abril 2014, 15:12 pm
Eres un exagerado. Su funcionamiento tampoco es tan complicado.

Lo único que hace la clase es almacenar el número en un vector de tipo "unsigned int". Lo he hecho así porque las operaciones matemáticas sobre tipos int o uint son más rápidas que ir carácter a carácter ( en el caso de almacenar el número en un string )... además, como efecto secundario, consume menos memoria.


Título: Re: Problema en variable int
Publicado por: amchacon en 29 Abril 2014, 15:45 pm
En la función toString ¿Que son estas lineas?
Código
  1. to_return = Mul2AddN( to_return, (data & 0x80000000)? 1 : 0 );
  2. data <<= 1;

¿Y binTostring que hace? ¿Imprimir el valor de los bits?


Título: Re: Problema en variable int
Publicado por: vangodp en 29 Abril 2014, 15:51 pm
¿ves lo que digo?  :laugh: :laugh: :laugh:

Puede que tu digas que tu código no sea para tanto :laugh: lo que no sabes es lo limitado que es la gente detrás de la pantalla. :D
Cuando el saber hace parte de tu día a día ignoras que la gente no sabe tanto como tu, te imaginas que todos tenemos la misma capacidad pero en realidad a algunos nos cuesta mas que a otros. Tener paciencia con nosotros lo novatos.  ;D
Lo que haces es grande, ayudas a la gente y no exiges nada a cambio, yo no podría pagar semejante ayuda con dinero. Así que al menos digo ¡¡¡Gracias*1000!!! ;-)

No soy grande...camino junto a ellos ^^


Título: Re: Problema en variable int
Publicado por: eferion en 29 Abril 2014, 16:01 pm
La función BinToString convierte a string la representación binaria del número.

Tal y como están estructurados los datos me parecía que era más fácil calcular la representación en base 10 de la siguiente forma:

* Creo un string con valor por defecto: "0"
* Recorro el array binario, empezando por los bits de mayor peso.
* Para cada iteración, multiplico el resultado del string por 2.
* Si el bit de turno en la iteración es '1', se lo sumo al string del resultado.

Los dos últimos pasos se realizan conjuntamente con la función Mul2AddN ( lo que viene a significar, multiplica por dos y suma N, donde N será 0 o 1 según proceda ).

la expresión:

Código
  1. (data & 0x80000000 )? 1 : 0

sirve para evaluar el bit de mayor peso de cada "tramo" de "unsigned int"... recordemos que está toda la representación metida en un vector.

Para poder evaluar los 32 bits de cada tramo tengo que hacer un desplazamiento binario, sustituyendo el bit de mayor peso por el siguiente... esto se hace con la siguiente línea:

Código
  1. data <<= 1;

Dicho con un ejemplo práctico la mecánica es la siguiente:

Código:
Número en binario: 1100101
resultado inicial: "0"

1a iteracion:
  "data & 0x800...": 1
  resultado = "0" * 2 + 1 = "1"

2a iteracion:
  "Data & 0x800...": 1
  resultado = "1" * 2 + 1 = "3"

3a iteracion:
  "Data & 0x800...": 0
  resultado = "3" * 2 + 0 = "6"

4a iteracion:
  "Data & 0x800...": 0
  resultado = "6" * 2 + 0 = "12"

5a iteracion:
  "Data & 0x800...": 1
  resultado = "12" * 2 + 1 = "25"

6a iteracion:
  "Data & 0x800...": 0
  resultado = "25" * 2 + 0 = "50"

7a iteracion:
  "Data & 0x800...": 1
  resultado = "50" * 2 + 1 = "101"

resultado final: "101"

modificado:

¿ves lo que digo?  :laugh: :laugh: :laugh:

Puede que tu digas que tu código no sea para tanto :laugh: lo que no sabes es lo limitado que es la gente detrás de la pantalla. :D
Cuando el saber hace parte de tu día a día ignoras que la gente no sabe tanto como tu, te imaginas que todos tenemos la misma capacidad pero en realidad a algunos nos cuesta mas que a otros. Tener paciencia con nosotros lo novatos.  ;D
Lo que haces es grande, ayudas a la gente y no exiges nada a cambio, yo no podría pagar semejante ayuda con dinero. Así que al menos digo ¡¡¡Gracias*1000!!! ;-)

No soy grande...camino junto a ellos ^^

Tu comentario me halaga, no lo puedo negar. Pero casi me pones a la altura de un semidios o algo así y tampoco es para tanto.

Muchas veces, cosas de estas son del tipo "idea feliz"... cuando las comprendes, ves que muchísimas veces la solución es más sencilla de lo que aparenta.

En cualquier caso, también ha quedado claro en algunos hilos que no soy infalible... sobretodo si posteo desde el móvil XDDDDD. Pero bueno, se hace lo que se puede con tal de ayudar.

Un saludo.


Título: Re: Problema en variable int
Publicado por: Blaster en 29 Abril 2014, 16:47 pm
Y el 0x80000000 de donde lo sacaste, que valor tiene y por que necesariamente debe ser este el indicado para hacer la comparación binario con dato

Saludos..


Título: Re: Problema en variable int
Publicado por: eferion en 29 Abril 2014, 16:59 pm
Y el 0x80000000 de donde lo sacaste, que valor tiene y por que necesariamente debe ser este el indicado para hacer la comparación binario con dato

Saludos..

Un int típico son 32 bytes. Unsigned int usa los mismos 32 bits, la diferencia es que al no usar bit de signo, amplía el rango posible de valores positivos.

Si tu pasas el número 0x80000000 a binario tienes el número:

Código:
8    0    0    0    0    0    0    0
1000 0000 0000 0000 0000 0000 0000 0000

Como ves, esa "máscara" junto con el operador binario and "&" permite saber si el dígito de mayor peso de una secuencia de 32 bits es 1 o 0... "X & 0x80000000" únicamente arrojará un resultado diferente a 0 cuando el bit de mayor peso sea 1... independientemente del estado del resto de los bits.

Si el tipo unsigned int ocupase un tamaño diferente a los ya comentados 32 bits habría que reajustar la máscara.


Título: Re: Problema en variable int
Publicado por: leosansan en 30 Abril 2014, 14:15 pm
¿Y hacerte una clase para manejar números grandes?

...............................................................................

Si estás programando en C el tema de las clases ya no te sirve... pero aún así sigue habiendo opciones.


Bueno si se trata de sumar números grandes en C, aunque no es necesaria, mejor con una función por si nos da por ampliar a resta, producto, etc y con arrays.

Y como comentó eferion:



Como es de esperar... ni está optimizada ni completa... está hecha en un rato para satisfacer el insaciable apetito de vangodp... pero vale de ejemplo.


Todo por un colega como vangodp, ahí va mi más que modesta propuesta en C:

Código
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. #define MAX_DIGITOS 200
  5.  
  6. void suma (char a[], char b[], char c[]){
  7.  int i,temp,residuo=0,lon_a,lon_b,dif;
  8.  lon_a = strlen(a);
  9.  lon_b = strlen(b);
  10.  if (lon_a > lon_b){
  11.    dif=lon_a-lon_b;
  12.    for (i=lon_b-1; i >=0;i--)
  13.      b[i+dif]=b[i];
  14.    for (i=0; i < dif;i++)
  15.        b[i]='0';
  16.  }
  17.  else if (lon_b > lon_a){
  18.    dif=lon_b-lon_a;
  19.    for (i=lon_a-1; i >=0;i--)
  20.      a[i+dif]=a[i];
  21.    for (i=0; i < dif;i++)
  22.        a[i]='0';
  23.  }
  24.  for (i=strlen(a)-1; i>=0;i-- ){
  25.    temp = a[i]-'0' + b[i]-'0' + residuo;
  26.    c[i+1]=temp%10+'0';
  27.    residuo=temp/10;
  28.  }
  29.  c[0] = residuo + '0';
  30.  if (c[0]=='0'){
  31.    for (i=0; i < strlen(a);i++ ){
  32.      c[i]=c[i+1];
  33.    }
  34.    c[strlen(a)]='\0';
  35.  }
  36.  c[strlen(a)+1]='\0';
  37. }
  38.  
  39. int main(void){
  40.  char a[MAX_DIGITOS] = /*  "99" */ /* "99" */ "123456123456123456123456123456123123";
  41.  char b[MAX_DIGITOS] = /* "199" */ /* "99" */  "983456123456123456123456123456123123";
  42.  char c[MAX_DIGITOS+1];
  43.  suma (a,b,c);
  44.  printf ("\n  %s +\n  %s=\n\n %s\n ",a,b,c);
  45.  return 0;
  46. }

La verdad que viendo el código de eferion el mio es como pobre, demasiado cortito.

Y sí, ya, sé debía usar memoria dinámica pero sólo quería algo rapidito para vangodp, ya si procede lo mejoro con las observaciones que aporten. E insisto, es un código modestito, sólo pretendía sumar un par de números grandes.

.....Bueno, está bien, lo mejoro. ¿Cómo?, pues lo de la memoria dinámica lo dejaré otra ocasión, ahora se me apetece otra cosa .......¿y si intentamos que los número grandes puedan estar en cualquier base de 2 a 36?. Es decir poder sumar números grandes en decimal o binario o octal o hexadecimal o ... y así sumar números grandes que estén entre las ya mencionadas bases de 2 a 36, los dos números en la misma base, claro...... otra cosa a mejorar. :)

De antemano aclaro que para bases superiores  a 10 no lo tengo del todo testado, pero creo que sí, que funciona:


Código
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. #define MAX_DIGITOS 300 /* o 3000*/
  5. #define DIGITOS   "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  6. #define BASE  16
  7.  
  8. void suma (char a[], char b[], char c[]){
  9.  int i,temp,temp_a,temp_b,residuo=0,lon_a,lon_b,dif,digit;
  10.  lon_a = strlen(a);
  11.  lon_b = strlen(b);
  12.  if (lon_a > lon_b){
  13.    dif=lon_a-lon_b;
  14.    for (i=lon_b-1; i >=0;i--)
  15.      b[i+dif]=b[i];
  16.    for (i=0; i < dif;i++)
  17.        b[i]='0';
  18.  }
  19.  else if (lon_b > lon_a){
  20.    dif=lon_b-lon_a;
  21.    for (i=lon_a-1; i >=0;i--)
  22.      a[i+dif]=a[i];
  23.    for (i=0; i < dif;i++)
  24.        a[i]='0';
  25.  }
  26.  for (i=strlen(a)-1; i>=0;i-- ){
  27.    if(a[i]-48>9 )
  28.      temp_a = a[i] -55 ;
  29.    else
  30.      temp_a = a[i] - '0';
  31.    if(b[i]-48>9)
  32.      temp_b = b[i] -55;
  33.    else
  34.      temp_b = b[i] - '0';
  35.    temp = temp_a + temp_b + residuo;
  36.    digit = DIGITOS [temp % BASE];
  37.    if (digit<10)
  38.      c[i+1]=DIGITOS [temp % BASE] + '0';
  39.    else
  40.      c[i+1]=DIGITOS [temp % BASE] ;
  41.    residuo = temp / BASE;
  42.  }
  43.  c[0] = residuo + '0';
  44.  if (c[0]=='0'){
  45.    for (i=0; i < strlen(a);i++ )
  46.      c[i]=c[i+1];
  47.    c[strlen(a)]='\0';
  48.  }
  49.  c[strlen(a)+1]='\0';
  50. }
  51.  
  52. int main(void){
  53.  /** ¡¡¡ NO OLVIDES CAMBIAR LA BASE DE (2-36) EN #DEFINE¡¡¡ **/
  54.  /** Tienes tres ejemplos: base 16, base 2, base 10 **/
  55.  char a[MAX_DIGITOS] = "A33A15FADBC9"  /*"1001001110111001" */ /*"123456123456123456123456123456123123"*/;
  56.  char b[MAX_DIGITOS] = "FFC593C5BA33A" /*"1001001110111001" */ /* "983456123456123456123456123456123123"*/;
  57.  char c[MAX_DIGITOS+1];
  58.  suma (a,b,c);
  59.  printf ("\n  %s +\n  %s=\n\n %s\n ",a,b,c);
  60.  return 0;
  61. }
  62.  

Y para que no digan, explico brevemente lo que hace el código:

* Calcula los tamaños de  ambos números y diferencio al de mayor tamaño del de menor.

* Al más pequeño lo relleno con ceros a la izquierda, previo movimiento hacia la derecha de todos sus dígitos para hacer espacio al principio a los ceros, hasta igualar las cifras del mayor.

* Y ya casi está, voy sumando los dígitos de cada uno de los dos números big y si suman más de 10, supuesto están en decimal, pongo el resto como dígito y "me llevo una", eso es el residuo que se sumará, si procede a los dos dígitos siguientes.

* Y para que quede bonito, si el primer caracter del resultado de la suma es cero lo quito moviendo  todos sus dígitos a la izquierda y acortando el tamaño en uno.

La intención es lo que cuenta, como suele decirse. De antemano disculpas si la he pifiado en algo,cosa que espero no haya ocurrido pero ....somos humanos y las prisas no son buenas consejeras. Así que si detectan bugs, porfi avisar.

Y sí, ya sé, el primer código podría usarlo para bases de 2 a 10 sin más que cambiar el "10" que aparece en el mencionado código , por "base" y esta tomar valores de 2 a 10, pero me apetecía ir más allá de la base en decimal xD.


¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Problema en variable int
Publicado por: eferion en 30 Abril 2014, 14:52 pm
Bueno si se trata de sumar números grandes en C, aunque no es necesaria, mejor con una función por si nos da por ampliar a resta, producto, etc y con arrays.

En su momento me planteé hacerlo en C... pero claro, la idea que tenía en mente era usar la codificación binaria en vez de por cadena de caracteres... y meter todas las funciones en C dejó de parecerme buena idea XD

La verdad que viendo el código de eferion el mio es como pobre, demasiado cortito.

Eso es porque tu, al usar cadenas de caracteres, no tienes que realizar conversiones...

¿y si intentamos que los número grandes puedan estar en cualquier base de 2 a 36?. Es decir poder sumar números grandes en decimal o binario o octal o hexadecimal o ... y así sumar números grandes que estén entre las ya mencionadas bases de 2 a 36, los dos números en la misma base, claro...

Es en esta parte donde el usar la codificación binaria ofrece una solución más sencilla... claro que antes me he tenido que currar el proceso de convertir base 10 a base 2...

Aclaro que me refiero a combinar diferentes bases en una misma operación.

La intención es lo que cuenta, como suele decirse. De antemano disculpas si la he pifiado en algo,cosa que espero no haya ocurrido pero ....somos humanos y las prisas no son buenas consejeras. Así que si detectan bugs, porfi avisar.

Pifiarla?? yo creo que cuando se hacen propuestas de estas tampoco es plan de que nadie exija que la solución funcione a la perfección en todos los casos... Yo con mi código hice un par de pruebas... si fuese para un desarrollo real le programaría una tira de pruebas bastante contundente.

Además, si alguien cree que puede hacerlo mejor, en vez de criticar, que exponga su solución... así además aprenderemos los demás.

¿No?

Por cierto, me falta alguien en esta conversación con toques matemáticos... qué ha sido de yoel_alejandro??


Título: Re: Problema en variable int
Publicado por: leosansan en 30 Abril 2014, 15:08 pm
.......................................................................
Pifiarla?? yo creo que cuando se hacen propuestas de estas tampoco es plan de que nadie exija que la solución funcione a la perfección en todos los casos... Yo con mi código hice un par de pruebas... si fuese para un desarrollo real le programaría una tira de pruebas bastante contundente.

Además, si alguien cree que puede hacerlo mejor, en vez de criticar, que exponga su solución... así además aprenderemos los demás.

¿No?

Por cierto, me falta alguien en esta conversación con toques matemáticos... qué ha sido de yoel_alejandro??


Gracias, muchas gracias eferion por tus palabras de comprensión.

Y es cierto, hace días que yoel_alejandro no aparece por el foro, que no "forro" y la verdad es que se hecha de menos sus aportaciones en C, y especialmente, sus puntos de vista matemáticos Con eso de que es de Venezuela espero sinceramente que no le haya pasado nada y que su ausencia se deba a cuestiones de trabajo que tal como están las cosas le vendría muy bien, como a todos, claro.

¡Un fuerte saludo!.




Título: Re: Problema en variable int
Publicado por: vangodp en 30 Abril 2014, 15:52 pm
gracias a todos chicos.
No te preocupes por si tu código es mejor o peor que el de un compañero leo. Eso nos sirve para tener una visión sencilla sobre el problema. Me sirve mucho igual que las propuestas mas avanzadas ya que soy iniciante. Como mínimo todos aprenderemos algo aquí o por lo menos cambiaremos ideas que nos haga mejorar. ;)
Aquí no es una universidad ni es un colegio de primaria, estamos encerrados todos en un mismo lugar, pero los niños de hoy serán los genios del mañana.
Si veo un código sencillo pues quizás abra ambos y vea lo que no veo en uno solo. ;)

¡¡Soys todos geniales!! Aquí nada se os resiste es fantástico.  ;D






Título: Re: Problema en variable int
Publicado por: eferion en 30 Abril 2014, 16:39 pm
Gracias, muchas gracias eferion por tus palabras de comprensión.

¿Gracias? no hace falta :), yo también aprendo cosas en este foro... las gracias son mutuas.


Título: Re: Problema en variable int
Publicado por: Blaster en 30 Abril 2014, 20:49 pm
Yo tambien quisiera dar un pequeño aporte con este pequeño codigo que me costo
un poco realizar opera muy bien con cifras muy grandes segun las pruebas que le realice..

Código
  1. #include <iostream>
  2. #include <cstring>
  3.  
  4. #define max 50
  5.  
  6. bool Sumar(char *str1, char *str2, char *r);
  7.  
  8. int main(void)
  9. {
  10.    char n1[] = "12345612345612345612345612345612312348513552";
  11.    char n2[] = "87654321123456787654321234567851515";
  12.    char suma[max] = "";
  13.  
  14.    Sumar(n1, n2, suma);
  15.    std::cout << n1 << "\n+\n" << n2 << "\n\n" << suma << std::endl;
  16.  
  17.    return 0;
  18. }
  19.  
  20. bool Sumar(char *str1, char *str2, char *r)
  21. {
  22.    char c1, c2;
  23.    int carry = 0;
  24.    int a = strlen(str1), b = strlen(str2);
  25.  
  26.    r[a > b? a : b] = 0;
  27.    do{
  28.         a--, b--;
  29.        (a < 0)? c1 = '0' : c1 = str1[a];
  30.        (b < 0)? c2 = '0' : c2 = str2[b];
  31.  
  32.        r[a > b? a : b] = carry + c1 + c2 - '0';
  33.        r[a > b ? a : b] > '9'? r[a > b ? a : b] -= 10, carry = 1 : carry = 0;
  34.    }while (a > 0 || b > 0);
  35.  
  36.    if (carry){
  37.      if (strlen(r) < max){
  38.         for (int i = strlen(r)+1; i > 0; i--)
  39.            r[i] = r[i-1];
  40.         r[0] = '1';
  41.         return false;
  42.        }
  43.    }
  44.    return true;
  45. }
  46.  
  47.  

Saludos..