Ответ 1
Вы используете функцию modf
:
double integral;
double fractional = modf(some_double, &integral);
Вы также можете применить его к целому числу, но будьте осторожны, вы можете переполнить целое число. Тогда результат не предсказуем.
Как мы можем извлечь десятичную часть числа с плавающей запятой и сохранить десятичную часть и целочисленную часть в две отдельные целочисленные переменные?
Вы используете функцию 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
в соответствии с вашими потребностями.
Я думаю, что использование строки - правильный способ пойти в этом случае, так как вы не знаете априори число цифр в десятичной части. Но это не будет работать для всех случаев (например, 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;
}
Я создал подпрограмму с двойным поплавком, он возвращает 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);
}
}
Даже я думал, как это сделать. Но я нашел способ. Попробуйте этот код
printf("Enter a floating number");
scanf("%d%c%d", &no, &dot, &dec);
printf("Number=%d Decimal part=%d", no, dec);
Вывод: -
Enter a floating number
23.13
Number=23 Decimal part=13
Вот еще один способ:
#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
Если вы просто хотите получить первое десятичное значение, решение действительно просто.
Вот пояснительный пример:
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.
Затем этот метод можно использовать для получения следующих десятичных символов, используя, например, 100 вместо 10 и т.д.
Просто обратите внимание, что если вы используете эту технику в системах реального времени, например, чтобы отобразить ее на 7-сегментном дисплее, она может не работать должным образом, потому что мы умножаемся на значение float, где умножение занимает много накладные расходы.
#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
Предположим, что A - это ваше целое число, тогда (int) A означает приведение числа к целому числу и будет целой частью, а другое - (A - (int) A) * 10 ^ n, здесь n - это число десятичных знаков, которые нужно сохранить,
Используйте плавающее число, чтобы вычесть значение с плавающей точкой, чтобы получить его дробную часть:
double fractional = some_double - floor(some_double);
Это предотвращает приведение типов к целому числу, что может вызвать переполнение, если число с плавающей запятой очень велико, и целочисленное значение даже не может его содержать.
Также для отрицательных значений этот код дает вам положительную дробную часть плавающего числа, так как floor() вычисляет наибольшее целочисленное значение, не превышающее входное значение.
Возможно, лучшая идея - решить проблему, пока данные находятся в формате String. Если у вас есть данные как String, вы можете проанализировать его в соответствии с десятичной точкой. Вы извлекаете интегральную и десятичную часть в качестве подстроки, а затем преобразуете эти подстроки в фактические целые числа.
Я сделал эту функцию, она работает нормально:
#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];
}