从C中的浮点数中提取小数部分
我们如何提取浮点数的小数部分,并将小数部分和整数部分存储到两个单独的整数variables中?
你使用modf
函数:
double integral; double fractional = modf(some_double, &integral);
你也可以把它转换成一个整数,但要注意你可能会溢出整数。 那么结果是不可预测的。
尝试这个:
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); }
对我来说,它产生:
Num = 23.345000, intpart = 23, decpart = 0.345000
这似乎是你所要求的。
快速的“坚果壳”最明显的答案似乎是:
#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);
您可以通过更改N_DECIMAL_POINTS_PRECISION
来更改您想要的小数点数以满足您的需要。
我认为在这种情况下使用string是正确的方法,因为您不知道小数部分的位数。 但是,它不适用于所有情况(例如1.005),正如@SingleNegationElimination所述。 这是我的承担:
#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; }
我创build了一个使用双精度浮点数的子程序,它返回2个整数值。
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); } }
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); } }
这是另一种方式:
#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 }
输出:
whole: 123 mantissa: 4567
如果你只是想得到第一个十进制值,解决scheme是非常简单的。
这里是一个解释性的例子:
int leftSideOfDecimalPoint = (int) initialFloatValue; // The cast from float to int keeps only the integer part int temp = (int) initialFloatValue * 10; int rightSideOfDecimalPoint = temp % 10;
举例来说,我们有一个初始的浮点值27.8。
- 通过只将最初的浮点数值转换为一个int值,就可以丢弃小数部分,只保留整数部分。
- 通过将初始浮点值乘以10得到278.0的结果,然后通过将此结果转换为int,给出值278
- 如果用10除278,得到27.8,其余8是小数点右边的值。 因此使用模数。
然后可以使用此技术通过使用例如100而不是10来获得以下小数字符,依此类推。
只要注意,如果您在实时系统上使用这种技术,例如将其显示在7段显示器上,则可能无法正常工作,因为我们乘以一个浮点值,乘法需要大量的开销时间。
也许最好的想法是解决问题,而数据是string格式。 如果你有数据作为string,你可以parsing它的小数点。 您将提取整数和小数部分作为子string,然后将这些子string转换为实际整数。
我做了这个function,似乎工作正常:
#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)); }
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]; }