TheMegalomaniac
TheMegalomaniac

Reputation: 161

Determining if a float has a fractional part?

Here is the problem: The game Totals can be played by any number of people. It starts with a total of 100 and each player in turn makes an integer displacement between -20 and 20 to that total. The winner is the player whose adjustment makes the total equal to 5. Using only the three variables given: total adjustment counter Here is what I have so far:

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

}

What I need: When a decimal number is entered it goes to the else. How do I determine if a float has a fractional part.

Upvotes: 15

Views: 22854

Answers (5)

Filip Ros&#233;en
Filip Ros&#233;en

Reputation: 63797

You can cast the float to an int and then compare it to your original variable. If they are the same there was no fractional part.

By using this method, there is no need for a temporary variable or a function call.

  float adj;

  ....     

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

Explanation

Since an int cannot handle fractions the value of your float will be truncated into an int (as an example (float)14.3 will be truncated into (int)14).

When comparing 14 to 14.3 it's obvious that they are not the same value, and therefore "fractional!" will be printed.

Upvotes: 27

sayth
sayth

Reputation: 7048

I am only learning C so tell me if I am wrong, please.

But if instead of using

scanf("%f",&adj);

if you use:

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

Therefore if the user typed anything other than a whole integer &IsUndef would not equal NULL and must have a fractional part sending the user to else.

maybe.

Upvotes: 1

litterbugkid
litterbugkid

Reputation: 3666

#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 finds the fractional part, so I guess testing whether it's equal to 0 or null will answer your question.

Upvotes: 16

Jonathan Leffler
Jonathan Leffler

Reputation: 753655

Using scanf() is problematic. If the user typed -5 +10 -15 -15 on the first line of input, then hit return, you'd process the 4 numbers in turn with scanf(). This is likely not what you wanted. Also, of course, if the user types +3 or more, then the first conversion stops once the space is read, and all subsequent conversions fail on the o or or, and the code goes into a loop. You must check the return value from scanf() to know whether it was able to convert anything.

The read-ahead problems are sufficiently severe that I'd go for the quasi-standard alternative of using fgets() to read a line of data, and then using sscanf() (that extra s is all important) to parse a number.

To determine whether a floating point number has a fractional part as well as an integer part, you could use the modf() or modff() function - the latter since your adj is a float:

#include <math.h>

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

The return value is the signed fractional part of x; the value in iptr is the integer part. Note that modff() may not be available in compilers (runtime libraries) that do not support C99. In that case, you may have to use double and modf(). However, it is probably as simple to restrict the user to entering integers with %d format and an integer type for adj; that's what I'd have done from the start.

Another point of detail: do you really want to count invalid numbers in the total number of attempts?

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

Clearly, I'm studiously ignoring the possibility that someone might type in more than 4095 characters before typing return.

Upvotes: 1

lhf
lhf

Reputation: 72312

if you want to know whether a real number x has no fractional part, try x==floor(x).

Upvotes: 3

Related Questions