[ Foro de BASIC ]

ELSE en Basic256

11-Jan-2014 19:20
Pablo Fernández Cabanas
3 Respuestas

Estoy usando el intérprete Basic256 que al parecer no admite ELSE.
Si pones un ELSE solo dice: ELSE without matching IF.
Pero si lo pones en la misma línea que un IF (para asegurar he copiado y pegado el ejemplo que se da en el curso)  da error en la línea que lo pongas. En mí caso pone "COMPILE ERROR on line 8: Syntax error around column 60.

Antes usaba qbasic64 pero un día me salió una ventana en negro al abrirlo y no volvió a funcionar, solo sale una ventana en negro.

Estoy haciendo el ejercicio de comprobar si un número es primo pero es mucho más cómodo usar ELSE sin embargo no puedo por ese error así que me gustaría que alguien me dijera si el código que estoy usando es correcto.
El código es el siguiente:


PRINT "Escribe un número para saber si es primo: ";
INPUT x
IF x=1 or x=0 THEN GOTO c
IF x<> 1 or 0 THEN GOTO normal
END
normal:
FOR i=1 to x
IF x/i= INT (x/i) and i=x and 1 THEN PRINT "Este número es primo"ELSE PRINT "Este número es compuesto"
NEXT i
END
c:
PRINT "1 y 0 no son primos, pero tampoco compuestos"
END



11-Jan-2014 21:18
Nacho Cabanes (+83)

Esa ha sido una de las últimas preguntas en el foro:

http://www.aprendeaprogramar.com/mod/forum/discuss.php?d=1005

La idea es que algunas versiones muy modernas, como Basic-256, pueden obligar a que descompongas el IF-ELSE en varias líneas, terminando con END IF, de modo que tu programa quedaría:


PRINT "Escribe un número para saber si es primo: "; 
INPUT x 
IF x=1 or x=0 THEN GOTO c 
IF x<> 1 or 0 THEN GOTO normal 
END 
normal: 
FOR i=1 to x 
IF x/i= INT (x/i) and i=x and 1 THEN 
    PRINT "Este número es primo"
ELSE
    PRINT "Este número es compuesto" 
END IF
NEXT i 
END 
c: 
PRINT "1 y 0 no son primos, pero tampoco compuestos" 
END


Aun así, te propongo dos mejoras:

Por una parte, no sé qué pretendes con el "and i=x and 1", pero suena a condición mal planteada. Además, con sólo comprobar un número que no sea divisor no puedes tener la certeza de si es primo o no, debes esperar al final de todas las comprobaciones (o a encontrar un divisor, y entonces no es primo). Una forma alternativa es contar los divisores, y si no había ninguno (excepto el 1 y el propio número), entonces el número era primo.

Por otra el GOTO es una orden arcaica, que crea programas caóticos, difíciles de leer, y deberías tratar de evitarla. Tu programa quedaría mucho más legible si usaras dos "if" anidados, así:


PRINT "Escribe un número para saber si es primo: "; 
INPUT x 

IF x=1 OR x=0 THEN 
    PRINT "1 y 0 no son primos, pero tampoco compuestos" 
ELSE
    cantidadDeDivisores = 0
    FOR divisor = 2 to x-1
        IF x/divisor = INT (x/divisor) THEN cantidadDeDivisores = cantidadDeDivisores + 1
    NEXT divisor 
    IF cantidadDeDivisores = 0 THEN 
        PRINT "Este número es primo"
    ELSE
        PRINT "Este número es compuesto" 
    END IF
END IF  

12-Jan-2014 17:21
Pablo Fernández Cabanas

Gracias por la aclaración. Me di cuenta de que el "and i=x and 1" estaba mal al enviar la pregunta, lo que quería poner era que si los divisores eran 1 y x pusiera que era primo pero esa no era la forma correcta.

Entiendo el segundo programa de hecho lo había probado pero no se me ocurría como hacer que contara los divisores pero ahora lo entiendo perfectamente, aún así en el ejemplo hay un par de errores, pones divisor= 2 to x-1 pero luego en vez de usar divisor usas i supongo que por corregirlo directamente del mío te habrás despistado y con ese código 2 da error. Por si alguien no consigue hacerlo y mira esta pregunta el código correcto sería:


PRINT "Escribe un número para saber si es primo: "; 
INPUT x 
 
IF x=1 OR x=0 THEN 
    PRINT "1 y 0 no son primos, pero tampoco compuestos" 
ELSE
    cantidadDeDivisores = 0
    FOR i = 1 to x-1
        IF x/i = INT (x/i) THEN cantidadDeDivisores = cantidadDeDivisores + 1
    NEXT i 
    IF cantidadDeDivisores = 1 THEN 
        PRINT "Este número es primo"
    ELSE
        PRINT "Este número es compuesto" 
    END IF
END IF  



12-Jan-2014 22:25
Nacho Cabanes (+83)

Tienes razón, con el despiste de usar "divisor" en un sitio e "i" en otro. Ya he corregido el fuente, pero conservo la palabra "divisor", para que las variables sean lo más claras posible.

En tu planteamiento final, desconcierta eso de que empieces a contar en 1 y termines en x-1. La definición habitual de primo es "un número que sólo es divisible por si mismo y por la unidad". Por eso, parece más razonable contar desde 1 hasta x, y en ese caso obtendrás sólo dos divisores si es primo, o eliminar los casos conocidos y contar desde 2 hasta x-1, de modo que si es primo obtendrías 0 divisores.

Como curiosidad, eso de usar un FOR para "contar todos los divisores" es una forma lenta de ver si es primo. Una alternativa más eficiente (más rápida en ejecución) es usar un WHILE: sigues buscando mientras no encuentres un divisor mayor que uno. Si el (primero) que encuentras es el propio número, quiere decir que era un número primo, pero si encuentras uno menor, no era primo. Piensa en el caso del número 50.000. El planteamiento inicial que estamos haciendo, contaría 50.000 números (o 49.998) para descubrir que hay más de 25.000 divisores y que, por tanto, no es primo. Por el contrario, el planteamiento con un WHILE probaría el 2, vería que sí es divisible y terminaría (con lo que, en ese caso concreto, sería más de 12.000 veces más rápido). Te lo dejo propuesto, por si lo quieres tomar como un reto a resolver.  ;-)






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)