Search code examples
cfloating-pointtype-conversiondoublefractions

How to extract fractional part of a double value without rounding in c


When i try to extract the fractional part of a double it seems to be rounding down in C, Is there a way to do it without rounding?

    double t = 8.2;
    int ipart = (int)t;
    long long val = abs((long long)(t*1000000));
    long long fpart = (val)%1000000;

fpart gives 199999, Is there a way to get it as 200000 without rounding down? Tried many ways but none of the methods seems to be working for all the numbers.

Intention is to finally convert this double into string which should have the exact value as "8.20000". If i can extract fraction part in long long variable then i can generate the string using snprintf.


Solution

  • How to extract fractional part of a double value without rounding ...?

    Use modf() from the standard C library.

    #include <math.h>
    
    double ipart;
    double fraction = modf(value, &ipart);
    printf("Fraction %g\n", fraction);
    printf("Whole number %g\n", ipart);
    

    The modf functions break the argument value into integral and fractional parts, each of which has the same type and sign as the argument. They store the integral part (in floating-point format) in the object pointed to by iptr.
    C17dr § 7.12.6.12 2


    Deeper into 8.2

    double can represent about 264 different values exactly. 8.2 is not one of them.

    With double t = 8.2;, t takes on a nearby value, which is exactly 8.199999999999999289457264239899814128875732421875 or
    81801439850948192/9007199254740992 due to the binary nature of common double.
    To find the fraction, use fraction*pow(2,DBL_MANT_DIG)/pow(2,DBL_MANT_DIG).

    Thus the goal of "to get it as 200000 without rounding down" as 200000/denominator for the fraction part of t is not possible.