Как исправить код для отделения целого числа от дробной части - PullRequest
0 голосов
/ 20 октября 2019

Я написал функцию, которая получает число с плавающей запятой, изменяет его на дробную часть и возвращает целую часть. Функция структурирована как оператор if-else (чтобы отличить положительные числа от отрицательных). Однако работает только первая часть заявления. В случае ниже, только когда я набираю отрицательное или нулевое число, код работает;когда я набираю положительное число, оно печатает только ноль. Проблема не в алгоритме отделения целого числа от дробной части, так как я также структурировал else-if, где первая часть была положительной по x, а также работала только первая часть.

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

//creates a function that changes the value of x to its
//fractional part and returns its integer part
float integerpart(float *x)
{
    float integer = 0;
    //If x is negative
    if (*x<0)
    {
        //I use an algorithm to separate its integer from its fractional part
        while (*x+1 <= integer)
        {
            integer--;
        }
        //I define the new value of x as its fractional part
        *x = *x - (integer);
    }
    else if (*x=0)
    {
        *x = 0;
        integer = 0;
    }
    //In the case in which x is positive
    else
    {
        //I do the inverse algorithm
        while (integer <= *x-1)
        {
            integer++;
        }
        *x-=integer;
    }
    //I return the integer part
    return integer;
}


int main()
{
    //Ask for the user to type a real number
    float number;
    printf("Type a real number:\n");
    scanf("%f", &number);
    //Uses the function to take the integer part of x
    float integ;
    integ = integerpart(&number);
    //Prints the integer and fractional part
    printf("Integer part = %f   Fractional Part = %f\n", integ, number);
    system("pause");
    return 0;
}

1 Ответ

1 голос
/ 22 октября 2019

Учитывайте это

while (integer <= *x-1)
{
    integer++;
}
*x-=integer;

Для больших значений x это будет мучительно медленно. Наихудший случай (, если вышеприведенное работает как задумано ) будет с максимальным значением ~ 1e38. Допустим, ваш компьютер может выполнять миллиард итераций цикла в секунду. Время выполнения составит ~ 1e29 секунд.

Однако вышеприведенное не будет работать так, как задумано. Для любого значения x больше чем ~ 1.6e7 пределы точности с плавающей запятой одинарной точности означают, что единица в последнем месте (ULP) больше, чем 1.0f. Конкретно это означает, что для значений, превышающих около 16 миллионов, оператор приращения ничего не делает. В результате цикл while никогда не завершится.

Как сказано в комментариях, рассмотрите возможность использования стандартных функций. В противном случае я предлагаю вам выделить знак мантиссы и показатели степени float.

...