Problema en variable int

Iniciado por meoit ARG, 28 Abril 2014, 21:56 PM

0 Miembros y 4 Visitantes están viendo este tema.

meoit ARG

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 (cpp) [Seleccionar]
if ((numero > 99999999999999999999) && (numero < 10000000000000000)) //si numero tiene 21 caracteres
{
}


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

vangodp

#1
18446744073709551615   <= unsigned long long int  :laugh:
99999999999999999999
pues ni idea amigo jajaj me has vencido hasta a mi XDD

cpu2

Es un numero de 64 bits "quad", prueba con un long long int.

Un saludo.

leosansan

Cita de: meoit ARG en 28 Abril 2014, 21:56 PM
Hola gente :)
.................................

Código (cpp) [Seleccionar]
if ((numero > 99999999999999999999) && (numero < 10000000000000000)) //si numero tiene 21 caracteres
{
}


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

Salu2 meoit =)

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

Código (cpp) [Seleccionar]
numero>99999999999999999999  y
numero<10000000000000000


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



meoit ARG

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

vangodp

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





eferion

¿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.

vangodp

#7
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:

eferion

#8
Código (cpp) [Seleccionar]

#include <bitset>
#include <iostream>
#include <string>
#include <vector>

class BigNum
{
  public:

    BigNum( int number = 0 );

    BigNum( const std::string& number );

    BigNum operator+( const BigNum& number );

    std::string ToBinString( ) const;

    std::string ToString( ) const;

  private:

    bool _negative;
    std::vector< unsigned int > _number;

    void Mul10AddN( unsigned int number );

    std::string Mul2( const std::string& number ) const;

    std::string Mul2AddN( const std::string& number, int carry ) const;

    void FromString( const std::string& number );
};

BigNum::BigNum( int number )
  : _negative( false )
{
  if ( number < 0 )
  {
    _negative = true;
    number = -number;
  }
  else if ( number > 0 )
    _number.push_back( number );
}

BigNum::BigNum( const std::string& number )
{
  FromString( number );
}

BigNum BigNum::operator +( const BigNum& number )
{
//  if ( number1._negative != number2._negative )
//  {
//    if ( number1._negative )
//    {
//      BigNum temp = number1;
//      temp._negative = false;
//      return number2 - temp;
//    }
//    else
//    {
//      BigNum temp = number2;
//      temp._negative = false;
//      return number1 - temp;
//    }
//  }

  BigNum to_return;
  to_return._negative = _negative;

  unsigned int carry = 0;
  unsigned int max = (_number.size( ) > number._number.size( ) )? _number.size( )
                                                                : number._number.size( );

  for ( unsigned int i=0; i < max; i++ )
  {
    unsigned long long temp = 0;

    if ( i < _number.size( ) )
      temp = static_cast< unsigned long long >( _number[ i ] );

    if ( i < number._number.size( ) )
      temp += static_cast< unsigned long long >( number._number[ i ] );

    temp += carry;

    to_return._number.push_back( static_cast< unsigned int >(temp & 0xFFFFFFFF) );
    carry = static_cast< unsigned int >(temp >> 32);
  }

  if ( carry != 0 )
    to_return._number.push_back( static_cast< unsigned int >( carry ) );

  return to_return;
}

std::string BigNum::ToBinString( ) const
{
  std::string to_return;

  for ( unsigned int i=_number.size( ) - 1; i < _number.size( ); i-- )
  {
    std::bitset< 32 > bits( static_cast< int >( _number[ i ] ) );
    to_return += bits.to_string( );
  }

  while ( to_return[ 0 ] == '0' )
    to_return.erase( to_return.begin( ) );

  int i = static_cast< int >( to_return.size( ) ) - 4;
  while ( i > 0 )
  {
    to_return.insert( i, 1, ' ' );
    i -= 4;
  }
  return to_return;
}

std::string BigNum::ToString() const
{
  std::string to_return = "0";

  for ( auto it = _number.rbegin( ); it != _number.rend( ); ++it )
  {
    int data = *it;
    for ( int i=0; i< 32; i++ )
    {
      to_return = Mul2AddN( to_return, (data & 0x80000000)? 1 : 0 );
      data <<= 1;
    }
  }

  return to_return;
}

void BigNum::Mul10AddN(unsigned int number)
{
  if ( _number.empty( ) )
  {
    _number.push_back( number );
    return;
  }

  unsigned long long carry = static_cast< unsigned long long >( number );
  unsigned long long ten = 10;
  for ( unsigned int i = 0; i < _number.size( ); i++ )
  {
    unsigned long long temp = static_cast< unsigned long long >( _number[ i ] ) * ten + carry;

    _number[ i ] = static_cast < unsigned int >( temp & 0xFFFFFFFF);
    carry = ( temp >> 32 );
  }

  if ( carry != 0 )
    _number.push_back( static_cast< unsigned int >( carry ) );
}

std::string BigNum::Mul2AddN(const std::string& number, int carry ) const
{
  std::string to_return;

  for ( auto it = number.rbegin( ); it != number.rend( ); ++it )
  {
    int temp = (*it - '0') * 2 + carry;

    if ( temp >= 10 )
    {
      temp -= 10;
      carry = 1;
    }
    else
      carry = 0;

    to_return.insert( 0, 1, temp + '0' );
  }

  if ( carry != 0 )
    to_return.insert( 0, 1, carry + '0' );

  return to_return;
}

void BigNum::FromString(const std::string& number)
{
  unsigned int i=0;
  if ( number[ i ] == '-' )
  {
    _negative = true;
    i++;
  }
  else
    _negative = false;

  _number.clear( );

  for ( ; i < number.length( ); i++ )
  {
    unsigned int digit = number[ i ] - 0x30;
    Mul10AddN( digit );
  }
}

int main( )
{
  BigNum a( 100 );
  BigNum b( "9000000000000" );

  BigNum c = a + b;

  std::cout << a.ToString( ) << std::endl
            << "+" << std::endl
            << b.ToString( ) << std::endl
            << "=" << std::endl
            << c.ToString( ) << std::endl;

  a = BigNum( "123456123456123456123456123456123123" );
  b = BigNum( "876543211234567876543212345678");
  c = a + b;


  std::cout << a.ToString( ) << std::endl
            << "+" << std::endl
            << b.ToString( ) << std::endl
            << "=" << std::endl
            << c.ToString( ) << std::endl;
}


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.

vangodp

no me equivocaba jeje Si no lo sabes tu quien va saberlo ^^
Ahora me falta un mes para analizar el código  :laugh: