Determining if a float has a fractional part?

17,331

Solution 1

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.

Solution 2

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

Solution 3

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

Solution 4

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.

Share:
17,331
TheMegalomaniac
Author by

TheMegalomaniac

Updated on June 04, 2022

Comments

  • TheMegalomaniac
    TheMegalomaniac almost 2 years

    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.

  • Kevin
    Kevin over 12 years
    You don't need the explicit cast back to float, it'll get cast automatically. Your solution isn't wrong, I'd just have written it as f == (int)f, which I find easier to read and understand.
  • lhf
    lhf over 12 years
    @sarnold, not in this case, no. Integers that can be represented as float or double are represented exactly and floor makes no mistake with those that aren't.
  • Filip Roséen - refp
    Filip Roséen - refp over 12 years
    @Kevin I edited that at the same time you wrote your comment, I then added some more information regarding the matter, thanks.
  • sarnold
    sarnold over 12 years
    Thanks for more detailed answer. :)
  • Oliver Charlesworth
    Oliver Charlesworth over 12 years
    I'm not convinced all the answers that use this technique are robust. If adj is actually the result of an intermediate calculation, it may be held in an extended-precision register. So the comparison may return false, even though when adj is later inspected, it actually turns out to be an integer value.
  • Oliver Charlesworth
    Oliver Charlesworth over 12 years
    I'm not convinced all the answers that use this technique are robust. If adj is actually the result of an intermediate calculation, it may be held in an extended-precision register. So the comparison may return false, even though when adj is later inspected, it actually turns out to be an integer value.
  • tothphu
    tothphu over 9 years
    Are you entirely sure that this works? 14 as a float number will really be represented by around 13.9999239894. So comparison will fail most of the time.