[c] How to extract the decimal part from a floating point number in C?

How can we extract the decimal part of a floating point number and store the decimal part and the integer part into two separate integer variables?

This question is related to c floating-point decimal numbers

The answer is


Here is another way:

#include <stdlib.h>
int main()
{
    char* inStr = "123.4567";         //the number we want to convert
    char* endptr;                     //unused char ptr for strtod

    char* loc = strchr(inStr, '.');
    long mantissa = strtod(loc+1, endptr);
    long whole = strtod(inStr, endptr);

    printf("whole: %d \n", whole);     //whole number portion
    printf("mantissa: %d", mantissa);  //decimal portion

}

http://codepad.org/jyHoBALU

Output:

whole: 123 
mantissa: 4567

I think that using string is the correct way to go in this case, since you don't know a priori the number of digits in the decimal part. But, it won't work for all cases (e.g. 1.005), as mentioned before by @SingleNegationElimination. Here is my take on this:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    char s_value[60], s_integral[60], s_fractional[60];
    int i, found = 0, count = 1, integral, fractional;

    scanf("%s", s_value);

    for (i = 0; s_value[i] != '\0'; i++)
    {
        if (!found)
        {
            if (s_value[i] == '.')
            {
                found = 1;
                s_integral[i] = '\0';
                continue;
            }
            s_integral[i] = s_value[i];
            count++;
        }
        else
            s_fractional[i - count] = s_value[i];
    }
    s_fractional[i - count] = '\0';

    integral = atoi(s_integral);
    fractional = atoi(s_fractional);
    printf("value = %s, integral = %d, fractional = %d\n",
        s_value, integral, fractional);

    return 0;
}

Use the floating number to subtract the floored value to get its fractional part:

double fractional = some_double - floor(some_double);

This prevents the typecasting to an integer, which may cause overflow if the floating number is very large that an integer value could not even contain it.

Also for negative values, this code gives you the positive fractional part of the floating number since floor() computes the largest integer value not greater than the input value.


cout<<"enter a decimal number\n";
cin>>str;
for(i=0;i<str.size();i++)
{
    if(str[i]=='.')
    break;
}

for(j=i+1;j<str.size();j++)
{
    cout<<str[j];
}

Use the floating number to subtract the floored value to get its fractional part:

double fractional = some_double - floor(some_double);

This prevents the typecasting to an integer, which may cause overflow if the floating number is very large that an integer value could not even contain it.

Also for negative values, this code gives you the positive fractional part of the floating number since floor() computes the largest integer value not greater than the input value.


 #include <stdio.h>
Int main ()
{
float f=56.75;
int a=(int)f;
int result=(f-a)*100;
printf ("integer = %d\n decimal part to integer 
 =%d\n",result);
}
Output:- 
integer =56
decimal part to integer = 75

Suppose A is your integer then (int)A, means casting the number to an integer and will be the integer part, the other is (A - (int)A)*10^n, here n is the number of decimals to keep.


I created a subroutine one using a double float, it returns 2 integer values.


void double2Ints(double f, int p, int *i, int *d)
{ 
  // f = float, p=decimal precision, i=integer, d=decimal
  int   li; 
  int   prec=1;

  for(int x=p;x>0;x--) 
  {
    prec*=10;
  };  // same as power(10,p)

  li = (int) f;              // get integer part
  *d = (int) ((f-li)*prec);  // get decimal part
  *i = li;
}

void test()
{ 
  double df = 3.14159265;
  int   i,d;
  for(int p=2;p<9;p++)
  {
    double2Ints(df, p, &i,&d); printf("d2i (%d) %f = %d.%d\r\n",p, df,i,d);
  }
}


Even I was thinking how to do it. But I found a way. Try this code

printf("Enter a floating number");
scanf("%d%c%d", &no, &dot, &dec);
printf("Number=%d Decimal part=%d", no, dec);

Output:-

Enter a floating number
23.13
Number=23 Decimal part=13

If you just want to get the first decimal value, the solution is really simple.

Here's an explanatory example:

int leftSideOfDecimalPoint = (int) initialFloatValue; // The cast from float to int keeps only the integer part

int temp = (int) initialFloatValue * 10;
int rightSideOfDecimalPoint = temp % 10;

Say for example we have an initial float value of 27.8 .

  • By just casting the initial float value to an int, you discard the fraction part and only keep the integer part.
  • By multiplying the initial float value by 10 we get a result of 278.0, then by casting this result to int, gives you the value of 278
  • If we divide 278 by 10, we get 27.8, of which the remainder is 8, which is the value at the right side of the decimal point. Thus use modulus.

This technique can then be used to get the following decimal characters by using for example 100 instead of 10, and so on.


Just take note that if you use this technique on real-time systems, for example to display it on a 7-segment display, it may not work properly because we are multiplying with a float value, where multiplication takes a lot of overhead time.


cout<<"enter a decimal number\n";
cin>>str;
for(i=0;i<str.size();i++)
{
    if(str[i]=='.')
    break;
}

for(j=i+1;j<str.size();j++)
{
    cout<<str[j];
}

Try this:

int main() {
  double num = 23.345;
  int intpart = (int)num;
  double decpart = num - intpart;
  printf("Num = %f, intpart = %d, decpart = %f\n", num, intpart, decpart);
}

For me, it produces:

Num = 23.345000, intpart = 23, decpart = 0.345000

Which appears to be what you're asking for.


The quick "in a nut shell" most obvious answer seems like:

#define N_DECIMAL_POINTS_PRECISION (1000) // n = 3. Three decimal points.

float f = 123.456;
int integerPart = (int)f;
int decimalPart = ((int)(f*N_DECIMAL_POINTS_PRECISION)%N_DECIMAL_POINTS_PRECISION);

You would change how many decimal points you want by changing the N_DECIMAL_POINTS_PRECISION to suit your needs.


I made this function, it seems to work fine:

#include <math.h>

void GetFloattoInt (double fnum, long precision, long *pe, long *pd)
{
  long pe_sign;
  long intpart;
  float decpart;

  if(fnum>=0)
  {
    pe_sign=1;
  }
  else
  {
    pe_sign=-1;
  }

  intpart=(long)fnum;
  decpart=fnum-intpart;

  *pe=intpart;  
  *pd=(((long)(decpart*pe_sign*pow(10,precision)))%(long)pow(10,precision));
}

You use the modf function:

double integral;
double fractional = modf(some_double, &integral);

You can also cast it to an integer, but be warned you may overflow the integer. The result is not predictable then.


I made this function, it seems to work fine:

#include <math.h>

void GetFloattoInt (double fnum, long precision, long *pe, long *pd)
{
  long pe_sign;
  long intpart;
  float decpart;

  if(fnum>=0)
  {
    pe_sign=1;
  }
  else
  {
    pe_sign=-1;
  }

  intpart=(long)fnum;
  decpart=fnum-intpart;

  *pe=intpart;  
  *pd=(((long)(decpart*pe_sign*pow(10,precision)))%(long)pow(10,precision));
}

Maybe the best idea is to solve the problem while the data is in String format. If you have the data as String, you may parse it according to the decimal point. You extract the integral and decimal part as Substrings and then convert these substrings to actual integers.


The quick "in a nut shell" most obvious answer seems like:

#define N_DECIMAL_POINTS_PRECISION (1000) // n = 3. Three decimal points.

float f = 123.456;
int integerPart = (int)f;
int decimalPart = ((int)(f*N_DECIMAL_POINTS_PRECISION)%N_DECIMAL_POINTS_PRECISION);

You would change how many decimal points you want by changing the N_DECIMAL_POINTS_PRECISION to suit your needs.


You use the modf function:

double integral;
double fractional = modf(some_double, &integral);

You can also cast it to an integer, but be warned you may overflow the integer. The result is not predictable then.


Here is another way:

#include <stdlib.h>
int main()
{
    char* inStr = "123.4567";         //the number we want to convert
    char* endptr;                     //unused char ptr for strtod

    char* loc = strchr(inStr, '.');
    long mantissa = strtod(loc+1, endptr);
    long whole = strtod(inStr, endptr);

    printf("whole: %d \n", whole);     //whole number portion
    printf("mantissa: %d", mantissa);  //decimal portion

}

http://codepad.org/jyHoBALU

Output:

whole: 123 
mantissa: 4567

 #include <stdio.h>
Int main ()
{
float f=56.75;
int a=(int)f;
int result=(f-a)*100;
printf ("integer = %d\n decimal part to integer 
 =%d\n",result);
}
Output:- 
integer =56
decimal part to integer = 75

Try this:

int main() {
  double num = 23.345;
  int intpart = (int)num;
  double decpart = num - intpart;
  printf("Num = %f, intpart = %d, decpart = %f\n", num, intpart, decpart);
}

For me, it produces:

Num = 23.345000, intpart = 23, decpart = 0.345000

Which appears to be what you're asking for.


Even I was thinking how to do it. But I found a way. Try this code

printf("Enter a floating number");
scanf("%d%c%d", &no, &dot, &dec);
printf("Number=%d Decimal part=%d", no, dec);

Output:-

Enter a floating number
23.13
Number=23 Decimal part=13

You use the modf function:

double integral;
double fractional = modf(some_double, &integral);

You can also cast it to an integer, but be warned you may overflow the integer. The result is not predictable then.


Suppose A is your integer then (int)A, means casting the number to an integer and will be the integer part, the other is (A - (int)A)*10^n, here n is the number of decimals to keep.


If you just want to get the first decimal value, the solution is really simple.

Here's an explanatory example:

int leftSideOfDecimalPoint = (int) initialFloatValue; // The cast from float to int keeps only the integer part

int temp = (int) initialFloatValue * 10;
int rightSideOfDecimalPoint = temp % 10;

Say for example we have an initial float value of 27.8 .

  • By just casting the initial float value to an int, you discard the fraction part and only keep the integer part.
  • By multiplying the initial float value by 10 we get a result of 278.0, then by casting this result to int, gives you the value of 278
  • If we divide 278 by 10, we get 27.8, of which the remainder is 8, which is the value at the right side of the decimal point. Thus use modulus.

This technique can then be used to get the following decimal characters by using for example 100 instead of 10, and so on.


Just take note that if you use this technique on real-time systems, for example to display it on a 7-segment display, it may not work properly because we are multiplying with a float value, where multiplication takes a lot of overhead time.


Maybe the best idea is to solve the problem while the data is in String format. If you have the data as String, you may parse it according to the decimal point. You extract the integral and decimal part as Substrings and then convert these substrings to actual integers.


You use the modf function:

double integral;
double fractional = modf(some_double, &integral);

You can also cast it to an integer, but be warned you may overflow the integer. The result is not predictable then.


I created a subroutine one using a double float, it returns 2 integer values.


void double2Ints(double f, int p, int *i, int *d)
{ 
  // f = float, p=decimal precision, i=integer, d=decimal
  int   li; 
  int   prec=1;

  for(int x=p;x>0;x--) 
  {
    prec*=10;
  };  // same as power(10,p)

  li = (int) f;              // get integer part
  *d = (int) ((f-li)*prec);  // get decimal part
  *i = li;
}

void test()
{ 
  double df = 3.14159265;
  int   i,d;
  for(int p=2;p<9;p++)
  {
    double2Ints(df, p, &i,&d); printf("d2i (%d) %f = %d.%d\r\n",p, df,i,d);
  }
}


Try this:

int main() {
  double num = 23.345;
  int intpart = (int)num;
  double decpart = num - intpart;
  printf("Num = %f, intpart = %d, decpart = %f\n", num, intpart, decpart);
}

For me, it produces:

Num = 23.345000, intpart = 23, decpart = 0.345000

Which appears to be what you're asking for.


Examples related to c

conflicting types for 'outchar' Can't compile C program on a Mac after upgrade to Mojave Program to find largest and second largest number in array Prime numbers between 1 to 100 in C Programming Language In c, in bool, true == 1 and false == 0? How I can print to stderr in C? Visual Studio Code includePath "error: assignment to expression with array type error" when I assign a struct field (C) Compiling an application for use in highly radioactive environments How can you print multiple variables inside a string using printf?

Examples related to floating-point

Convert list or numpy array of single element to float in python Convert float to string with precision & number of decimal digits specified? Float and double datatype in Java C convert floating point to int Convert String to Float in Swift How do I change data-type of pandas data frame to string with a defined format? How to check if a float value is a whole number Convert floats to ints in Pandas? Converting Float to Dollars and Cents Format / Suppress Scientific Notation from Python Pandas Aggregation Results

Examples related to decimal

Java and unlimited decimal places? What are the parameters for the number Pipe - Angular 2 Limit to 2 decimal places with a simple pipe C++ - Decimal to binary converting Using Math.round to round to one decimal place? String to decimal conversion: dot separation instead of comma Python: Remove division decimal Converting Decimal to Binary Java Check if decimal value is null Remove useless zero digits from decimals in PHP

Examples related to numbers

how to display a javascript var in html body How to label scatterplot points by name? Allow 2 decimal places in <input type="number"> Why does the html input with type "number" allow the letter 'e' to be entered in the field? Explanation on Integer.MAX_VALUE and Integer.MIN_VALUE to find min and max value in an array Input type "number" won't resize C++ - how to find the length of an integer How to Generate a random number of fixed length using JavaScript? How do you check in python whether a string contains only numbers? Turn a single number into single digits Python