How does this method of calculating large numbers work?

Typically, to handle integers that exceed the range of a long long C ++ code, you will have to represent them as a string and perform operations on them that way. But I found this code on the Internet that seems to work like magic. It calculates any sum of powers of two (without 2 ^ 0), although it cannot be stored for a long time.

#include <iostream>  
#include <cmath>  
#include <iomanip>  
#include <sstream>  
using namespace std;

int main() {
    int n;
    stringstream ss;
    cin >> n;

    ss << fixed << setprecision(0) << pow(2, n + 1) - 2;

    if (n >= 54) {
        string a = ss.str();

        a[a.size() - 1] = ((a[a.size() - 1] - 48) - 2) + 48;

        cout << a;
        return 0;
    }

    cout << ss.str();

}

How it works? Will it work for any operation with large numbers? If the value of n is very large (I tried 1024), it just prints "inf". What is the upper limit of the range of numbers that can be calculated this way?

What exactly does this part do and why does it do it?

a[a.size() - 1] = ((a[a.size() - 1] - 48) - 2) + 48;
+4
2

?

, . , .


, ?

, .

std::numeric_limits<double>::max(). . . std::pow(std::numeric_limits<double>::radix, std::numeric_limits<double>::digits).


?

a[a.size() - 1] = ((a[a.size() - 1] - 48) - 2) + 48;

a[a.size() - 1] -= 2;

2 ( ) . , 2 0 1 10 ( 2 0), .

, pow(2, n + 1) - 2 == pow(2, n + 1) n >= 54. , IEEE-754, std::pow(std::numeric_limits<double>::radix, std::numeric_limits<double>::digits) std::pow(2, 54). n 54, std::pow(2, 54 + 1) , 2, , . ! . .

2 ( ) , .

+6

.

, (, IEEE 754) 2 N N ( ).

,

unsigned N = ...;

double d = std::pow(2.0, N);
std::stringstream str;
str << std::fixed << std::setprecision(0) << d;
std::string s = str.str();

2 N N.

, , 2 N (N > 0) ...0 , , 1 1 2 ( ). , 2 N + k k = -2, -1,0, + 1,

s[s.size() - 1] += k;

, 2 ...98, , k = + 2, + 3

if ((s[s.size() - 1] += k) > '9')
{
  s[s.size() - 1] -= 10;
  ++s[s.size() - 2];
}

1 . ( ).

, 2 ...02, k = -3, -4

if ((s[s.size() - 1] += k) < '0')
{
  s[s.size() - 1] += 10;
  --s[s.size() - 2];
}

, 2 ( pow(2, n + 1) - 2). 48 .

+3

Source: https://habr.com/ru/post/1672026/


All Articles