Числа с плавающей запятой не работают должным образом - PullRequest
1 голос
/ 08 сентября 2011

В приведенном ниже коде, когда я даю ввод как 1 10 2 1 2 2, сумма печатается как 52, а сумма 3 как 31.200001, тогда как она должна быть 31.200000

int main(){

    int t,n,i,a[2000],m,j,f;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        scanf("%d",&f);
        for(i=0;i<f;i++){
            scanf("%d",&a[i]);
        }
        scanf("%d",&m);
        if(n!=0){
            int sum=n*(n+1)/2;
            int sum2=0;
            for(j=0;j<i;j++){
                sum2+=a[j];
            }
            sum-=sum2;
            printf("%d\n",sum);
            float sum3;
            if(n%2==0) sum3=(1.0-2.0*m/n)*sum;
            else sum3=(1.0-2.0*m/(n+1))*sum;
            printf("%f\n",sum3);
        }
        else printf("0.0000\n");
    }
    return 0;
}

Ответы [ 6 ]

5 голосов
/ 08 сентября 2011

С Руководство по числам с плавающей точкой :

Почему мои числа, такие как 0,1 + 0,2, не складываются в хороший раунд 0,3, а вместо этого яполучить странный результат, такой как 0.30000000000000004?

Поскольку внутренне, компьютеры используют формат (двоичная с плавающей запятой), который не может точно представить число как 0.1, 0.2 или 0.3 вообще.

Когда код компилируется или интерпретируется, ваш «0.1» уже округляется до ближайшего числа в этом формате, что приводит к небольшой ошибке округления даже до того, как произойдет вычисление.

2 голосов
/ 08 сентября 2011

Десятичное число 31.2 не представляется в виде двоичной дроби. Точнее говоря, ближайшее значение типа float равно 31.200000762939453125, что в точности равно 8178893 * 2 -18 .

Если вам нужно число, которое ближе к десятичному 31.2, рассмотрите возможность использования типа double, где ваш результат будет 31.199999999999999289457264239899814128875732421875 или 8782019273372467 * 2 -48

0 голосов
/ 19 июня 2013

Вы можете использовать printf("%g\n",sum3); вместо printf("%f\n",sum3); в вашем коде, чтобы получить правильный вывод ..

Надеюсь, это сработает.

0 голосов
/ 08 сентября 2011

.. Но вы можете попытаться уменьшить эту возможность. Вы должны принять во внимание показатели для сложения / вычитания среди прочего.

0 голосов
/ 08 сентября 2011

31.2 не является представимым числом в двоичной переменной с плавающей точкой.Независимо от того, какой расчет используется для его получения, вы никогда не получите поплавок, который точно равен 31.2.Ответ, который вы получили, настолько хорош, насколько вы можете разумно ожидать.

0 голосов
/ 08 сентября 2011

Такова природа float с.Они не гарантируют абсолютной точности.

См. здесь для более подробной информации о том, как и почему это так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...