@nishe

Почему при умножении чисел типа float теряется один десятичный порядок на каждой итерации и как этого избежать?

Вся проблема кода находится в функции Bakery_map. При вычислении арифметических операций программа теряет один знак после запятой. Как этого избежать?
int float_comparison_N(float a, float b, int N) {

    for (int i = 0; i < N; i++) {
        a *= 10;
        b *= 10;
        if ((int)a != (int)b) return 0;
        a -= (int)a;
        b -= (int)b;
    }
    return 1;
}


float Bakers_map(float x) {

    if (x < 0.5)
        return 2.0 * x;
    else
        return 2.0 * x - 1.0;
}

int main() {

    setlocale(LC_ALL, "Rus");

    float a = 0.2324325;
    float b = 0.2324325;

    while (a==b)
    {
        a = Bakers_map(a);
        b = Bakers_map(b);
        std::cout << std::setprecision(100) << a << "\t\t\t";
        std::cout << std::setprecision(100) << b << std::endl;
    }


    return 0;
}


Пример выходных данных:
0.4648649990558624267578125                     0.4648649990558624267578125
0.929729998111724853515625                      0.929729998111724853515625
0.85945999622344970703125                       0.85945999622344970703125
0.7189199924468994140625                        0.7189199924468994140625
0.437839984893798828125                 0.437839984893798828125
0.87567996978759765625                  0.87567996978759765625
0.7513599395751953125                   0.7513599395751953125
0.502719879150390625                    0.502719879150390625
0.00543975830078125                     0.00543975830078125
0.0108795166015625                      0.0108795166015625
0.021759033203125                       0.021759033203125
0.04351806640625                        0.04351806640625
0.0870361328125                 0.0870361328125
0.174072265625                  0.174072265625
0.34814453125                   0.34814453125
0.6962890625                    0.6962890625
0.392578125                     0.392578125
0.78515625                      0.78515625
0.5703125                       0.5703125
0.140625                        0.140625
0.28125                 0.28125
0.5625                  0.5625
0.125                   0.125
0.25                    0.25
0.5                     0.5
0                       0
0                       0
0                       0
0                       0
  • Вопрос задан
  • 152 просмотра
Решения вопроса 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Представление любого числа в компьютере состоит из конечного числа битов. Умножая число на 2, вы просто сдвигаете его на один бит влево, заполняя младший (правый) бит нулём. А поскольку вы вычитаете единицу, если она образовалась, то с каждой итерацией в вашем числе всё меньше значащих битов.

0.140625 = 0.0010012
0.140625 * 2 = 0.28125 = 0.0100102
0.28125 * 2 = 0.5625 = 0.1001002
0.5625 * 2 - 1 = 0.125 = 0.0010002
0.125 * 2 = 0.25 = 0.0100002
0.25 * 2 = 0.5 = 0.1000002
0.5 * 2 - 1= 0 = 0.0000002
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
AgentSmith
@AgentSmith
Это мой правильный ответ на твой вопрос
Никак. Это основа устройства компьютеров.
Изучай основы почему такое происходит.
P.S. Я теперь понимаю почему у нас Хром жрёт всю память, а простейшие Notepad и прочие жрут больше 100 мегов памяти. Помнится, винда 3.0 полностью умещалась на харде в 40 МЕГАБАЙТ! - Размер одной картинки в современном смартфоне. А там даже проводник был и Notepad
Ответ написан
Комментировать
Adamos
@Adamos
Прекрасная задача для собеседования, я так считаю.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы