Números perfectos (lenguaje C)

Iniciado por NOB2014, 25 Septiembre 2014, 20:05 PM

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

ivancea96

Usa unsigned long long, para números más grandes.

Blaster

Cita de: NOB2014 en 28 Septiembre 2014, 00:58 AM
Estoy de acuerdo y con esa modificación los primos están correctos pero los perfectos me parece que no.-

El problema con el código del compañero es que de igual manera procesa los primos no validos (23, 29) y también mencionar el desbordamiento de enteros producido, he aquí un ejemplo que calcula los ocho números perfectos :

Código (cpp) [Seleccionar]
#include <math.h>
#include <stdio.h>
#include <limits.h>

typedef enum { FALSE = 0, TRUE = 1 } BOOL;

BOOL is_prime( int p )
{
    if( p == 2 ) return TRUE;
    else if( p <= 1 || p % 2 == 0 ) return FALSE;
    else
    {
        BOOL prime = TRUE;
        const int to = sqrt(p);
        int i;
        for(i = 3; i <= to; i+=2)
            if (!(prime = p % i))
                break;
        return prime;
    }
}

BOOL is_mersenne_prime( int p )
{
    if( p == 2 )
        return TRUE;
    else
    {
        long long unsigned m_p = ( 1U << p ) - 1;
        long long unsigned s = 4;
        int i;
        for (i = 3; i <= p; i++)
        {
            s = (s * s - 2) % m_p;
        }
        return s == 0;
    }
}

int main(int argc, char **argv)
{
    const int upb = log2l(ULLONG_MAX)/2;
    int p;

    for( p = 2; p <= upb; p++ )
    {
        if( is_prime(p) && is_mersenne_prime(p) )
            printf(" %llu\n", (long long unsigned)(1U << (p - 1)) * ((1U << p) - 1));
    }
    printf("\n");

    return 0;
}


Puedes comprobarlo aquí :

http://www.vaxasoftware.com/doc_edu/mat/numperfe_esp.pdf

Un saludo

rir3760

Cita de: engel lex en 25 Septiembre 2014, 22:20 PMme diste algo que investigar, estuve viendo la progesion completa (sin importar si eran primos o no) en binario y son muy simple en ese aspecto... pero me da un error que no descubro la razón
El problema es que solo presentas la salida del programa, sin el código fuente no es posible conocer la causa del error (imagino tiene que ver con tu otra duda).

Cita de: engel lex en 27 Septiembre 2014, 19:49 PMpara ser sincero se que el metodo 2 necesita casting de tipo, pero no estoy seguro por que
El segundo metodo es:
long unsigned int numero_perfecto_metodo2(int primo)
{
   unsigned long int resultado;
   resultado = (unsigned long int) ((1 << primo) - 1) << (primo - 1);
   return resultado;
}

El cual se puede abreviar a:
long unsigned int numero_perfecto_metodo2(int primo)
{
   return ((1 << primo) - 1) << (primo - 1);
}

El problema ahí es la primera literal 1, esta es de tipo signed int y puede, dependiendo del desplazamiento, generar un numero negativo. Para solucionarlo lo mas fácil es indicar que el tipo de ella es unsigned long mediante sufijos: 1UL.

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language