Почему эти два фрагмента кода дают разные результаты? (Float, двойная точность) - PullRequest
0 голосов
/ 25 января 2012

Я только начинаю изучать C ++ и возиться с числами с плавающей запятой и двойными значениями. Ниже приведены два фрагмента кода, которые, как мне кажется, делают одно и то же, но дают разные результаты. Что мне не хватает? Может кто-то объяснить ошибку точности, первый код должен получить результат, отличный от второго.

int _tmain(int argc, _TCHAR* argv[])
{
    const float f = 0.1;
    const double d = 0.1;
    int counter = 0;

    for(counter; ((double)counter * f - (double)counter * d) < 0.34; counter++) {}

    cout << "Iterations = " << counter << "\n" ;

    system("pause");
    return 0;
}


int main (int argc, const char * argv[])
{
    float time_f = 0.1;    
    double time_d = 0.1;
    float total_f = 0;
    double total_d = 0;
    int count=0;
    double difference = 0;
    while (true) {
        total_d = count * time_d;
        total_f = count * time_f;
        if(total_f - total_d >= 0.34){

            break;
        }
        count++;

    }
    std::cout <<  count << "\n";
    system("pause");
}

Я изменил приведение моего цикла for для float и double, но значение не отличается.

Ответы [ 3 ]

2 голосов
/ 25 января 2012

Оба float и double имеют конечное представление, что означает, что они принять ряд конкретных значений, а не просто какие-либо реальные значения. В в частности, в вашем примере 0.1 не имеет точной плавающей запятой представление на любой современной машине, которую я знаю (все из которых используют базу в их реализации это степень 2 - 0.1 равно 1/5 * 1/2, и ничто, кратное 1/5, не может иметь конечного представление, если основание не кратно 5).

В результате либо float, либо double имеют один и тот же базовый представление (обычно это не так), или будет разница, как как только count отличается от 0.

Обычная ссылка на эту тему & Ldquo; Что Каждый ученый должен знать о с плавающей точкой Арифметика & Rdquo ;. Пока вы не прочитали и не поняли (или, по крайней мере, понял значение) это, вы не должны трогать машину плавающей точка.

1 голос
/ 25 января 2012

Разница между этими двумя фрагментами кода в приведении. counter * f приводится к удвоению в первом фрагменте и сохраняется в переменную типа float во втором.

Вот пример того, как это может выглядеть:

#include <stdio.h>

int main(int argc, char* argv[])
{
    const float f = 0.1;
    const double d = 0.1;
    int count = 0;

    for(count; (double)(count * f) - (double)(count * d) < 0.34; count++);

    printf("Iterations = %d\n", count);
    count = 0;

    while (true)
    {
        double total_d = count * d; // is equal to (double)(count * d)
        double total_f = count * f; // is equal to (double)(count * f)
        if (total_f - total_d >= 0.34)
            break;
        count++;
    }
    printf("Iterations = %d\n", count);

    return 0;
}
0 голосов
/ 25 января 2012

Здесь вы еще не удвоили счет:

...