2011-12-18 19 views
8

Aquí está el problema: Los totales del juego pueden ser jugados por cualquier cantidad de personas. Comienza con un total de 100 y cada jugador a su vez realiza un desplazamiento entero entre -20 y 20 a ese total. El ganador es el jugador cuyo ajuste hace que el total igual a 5. El uso de sólo las tres variables dada: total de ajuste contador Aquí es lo que tengo hasta ahora:¿Cómo determinar si un flotador tiene una parte fraccionaria?

#include <stdio.h> 
int main (void) 
{ 
    int counter=0; 
    float adj; 
    int ttl=100; 

    printf("You all know the rules now lets begin!!!\n\n\nWe start with 100. What is\n"); 

    while (ttl!=5) 
    { 
     printf("YOUR ADJUSTMENT?"); 
     scanf("%f",&adj); 
     counter++; 
     if (adj<=20 && adj>=-20) 
     { 
     ttl=ttl+adj; 
     printf("The total is %d\n",ttl); 
     } 
     else 
     { 
     printf ("I'm sorry. Do you not know the rules?\n"); 
     } 
    } 
    printf("The game is won in %d steps!",counter); 

} 

Lo que necesito: Cuando un número decimal ingresado va al else. ¿Cómo puedo determinar si un flotante tiene una parte fraccionaria?

+0

En un nivel binario, ningún número de coma flotante tiene un decimal. http://en.wikipedia.org/wiki/IEEE_754-2008 –

+0

Estamos hablando de carrozas aquí. Siempre "tiene un decimal". Use un 'doble' en su lugar. (FYI @Chris y quiero decir lo mismo) –

+2

@TomvanderWoerdt: ¿Qué diferencia hace 'double'? –

Respuesta

3

si quiere saber si un número real x no tiene una parte fraccionaria, intente x==floor(x).

+0

@sarnold, no en este caso, no. Los enteros que se pueden representar como 'float' o' double' se representan exactamente y 'floor' no se confunde con los que no lo son. – lhf

+0

Gracias por una respuesta más detallada. :) – sarnold

+0

No estoy seguro de que todas las respuestas que usan esta técnica sean sólidas. Si 'adj' es realmente el resultado de un cálculo intermedio, puede mantenerse en un registro de precisión extendida. Entonces la comparación puede devolver 'false', aunque cuando' adj' se inspecciona más tarde, en realidad resulta ser un valor entero. –

10
#include <stdio.h> 
#include <math.h> 

int main() 
{ 
    float param, fractpart, intpart; 

    param = 3.14159265; 
    fractpart = modff (param , &intpart); 
    return 0; 
} 

http://www.cplusplus.com/reference/clibrary/cmath/modf/

modff encuentra la parte fraccionaria, así que supongo que probar si es igual a 0 o null va a responder a su pregunta.

+0

debe ser la respuesta aceptada, ¡gracias! – VivienLeger

13

Puede convertir el float en un int y luego compararlo con su variable original. Si son iguales, no hubo parte fraccionaria.

Al usar este método no hay necesidad de una variable temporal o una llamada de función.

float adj; 

    ....  

    if (adj == (int)adj) 
    printf ("no fractional!\n"); 
    else 
    printf ("fractional!\n"); 

Explicación

Desde un int no puede manejar fracciones el valor de su float se truncarán en un int (como un ejemplo (float)14.3 será truncado en (int)14).

Al comparar 14 con 14.3 es obvio que no tienen el mismo valor, y por lo tanto "¡fraccionario!" será impreso.

+2

No necesita la devolución explícita a 'float', se lanzará automáticamente. Su solución no está mal, solo la habría escrito como 'f == (int) f', que me resulta más fácil de leer y comprender. – Kevin

+0

@Kevin Edité que, al mismo tiempo que escribía su comentario, agregué más información sobre el asunto, gracias. –

+2

No estoy seguro de que todas las respuestas que usan esta técnica sean sólidas.Si 'adj' es realmente el resultado de un cálculo intermedio, puede mantenerse en un registro de precisión extendida. Entonces la comparación puede devolver 'false', aunque cuando' adj' se inspecciona más tarde, en realidad resulta ser un valor entero. –

0

Usar scanf() es problemático. Si el usuario tipeó -5 +10 -15 -15 en la primera línea de entrada, luego presionó regresar, procesaría los 4 números sucesivamente con scanf(). Es probable que esto no sea lo que querías. Además, por supuesto, si el usuario escribe +3 or more, la primera conversión se detiene una vez que se lee el espacio, y todas las conversiones posteriores fallan en o o or, y el código entra en un bucle. Debe verificar el valor de retorno desde scanf() para saber si fue capaz de convertir cualquier cosa.

Los problemas de lectura anticipada son suficientemente grave que yo iría a la alternativa casi estándar de utilizar fgets() para leer una línea de datos, y luego usando sscanf() (ese extra s es lo más importante) para analizar un número.

Para determinar si un número de coma flotante tiene una parte fraccionaria, así como una parte entera, se puede utilizar la función de modf() or modff() - este último desde su adj es una float:

#include <math.h> 

double modf(double x, double *iptr); 
float modff(float value, float *iptr); 

El valor de retorno es el parte fraccional firmada de x; el valor en iptr es la parte entera. Tenga en cuenta que modff() puede no estar disponible en los compiladores (bibliotecas de tiempo de ejecución) que no son compatibles con C99. En ese caso, puede que tenga que usar double y modf(). Sin embargo, probablemente sea tan simple restringir al usuario a ingresar enteros con el formato %d y un tipo entero para adj; eso es lo que habría hecho desde el principio.

Otro punto de detalle: ¿realmente desea contar números inválidos en el número total de intentos?

#include <stdio.h> 
#include <math.h> 

int main(void) 
{ 
    int counter=0; 
    int ttl=100; 

    printf("You all know the rules now lets begin!!!\n" 
      "\n\nWe start with 100. What is\n"); 

    while (ttl != 5) 
    { 
     char buffer[4096]; 
     float a_int; 
     float adj; 

     printf("YOUR ADJUSTMENT?"); 
     if (fgets(buffer, sizeof(buffer), stdin) == 0) 
      break; 
     if (sscanf("%f", &adj) != 1) 
      break; 
     if (adj<=20 && adj>=-20 && modff(adj, &a_int) == 0.0) 
     { 
      counter++; // Not counting invalid numbers 
      ttl += adj; 
      printf("The total is %d\n", ttl); 
     } 
     else 
     { 
      printf ("I'm sorry. Do you not know the rules?\n"); 
     } 
    } 

    if (ttl == 5) 
     printf("The game is won in %d steps!\n", counter); 
    else 
     printf("No-one wins; the total is not 5\n"); 
    return(0); 
} 

Claramente, estoy ignorar deliberadamente la posibilidad de que alguien pueda escribir en más de 4095 caracteres antes de escribir retorno.

0

Solo estoy aprendiendo C, así que dime si me equivoco, por favor.

Pero si en lugar de utilizar

scanf("%f",&adj); 

si utilizar:

scanf("%d%d", &adj, &IsUndef); 

Por lo tanto, si el usuario ha escrito otra cosa que no sea un número entero & IsUndef no sería igual a NULL y debe tener una parte fraccionaria enviando al usuario a else.

quizás.

Cuestiones relacionadas