N
N
nishe2021-12-21 00:33:37
C++ / C#
nishe, 2021-12-21 00:33:37

Why is one decimal exponent lost at each iteration when multiplying float numbers, and how can this be avoided?

The whole problem of the code is in the Bakery_map function. When calculating arithmetic operations, the program loses one decimal place. How to avoid it?

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

Answer the question

In order to leave comments, you need to log in

3 answer(s)
R
Rsa97, 2021-12-21
@nishe

The representation of any number in a computer consists of a finite number of bits. When multiplying a number by 2, you simply shift it one bit to the left, filling the least significant (right) bit with zero. And since you're subtracting one if there's one, there are fewer significant bits in your number with each iteration.
0.140625 = 0.001001 2
0.140625 * 2 = 0.28125 = 0.010010 2
0.28125 * 2 = 0.5625 = 0.100100 2
0.5625 * 2 - 1 = 0.125 = 0.001000 2
0.125 * 2 = 0.25 = 0.010000 2
0.25 * 2 = 0.5 = 0.100000 2
0.0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 2 - 1= 0 = 0.000000 2

N
Nikolay Savelyev, 2021-12-21
@AgentSmith

No way. It is the foundation of computers.
Learn the basics of why this happens.
PS Now I understand why we have Chrome eats all the memory, and the simplest Notepad and others eat more than 100 megs of memory. I remember that Windows 3.0 completely fit on the hard drive in 40 MB! - The size of one picture in a modern smartphone. And there was even a conductor and Notepad

A
Adamos, 2021-12-21
@Adamos

Great job for an interview, in my opinion.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question