Home > database >  why for loop is not work correctly for a simple multiplication numbers 1 to 50?
why for loop is not work correctly for a simple multiplication numbers 1 to 50?

Time:12-07

code:

#include <iostream>
using namespace std;

int main() {
  int answer = 1;
  int i = 1;
  for (; i <= 50; i  ){
    answer = answer * i;
  }
  cout << answer << endl;
  
  return 0;
}

resault :

0

...Program finished with exit code 0
Press ENTER to exit console.

when i run this code in an online c compiler, it shows me zero(0) in console. why?

CodePudding user response:

I will answer specifically the asked question "Why?" and not the one added in the comments "How?".

You get the result 0 because one of the intermediate values of answer is 0 and multiplying anything with it will stay 0.

Here are the intermediate values (I found them by moving your output into the loop.):

1
2
6
24
120
720
5040
40320
362880
3628800
39916800
479001600
1932053504
1278945280
2004310016
2004189184
-288522240
-898433024
109641728
-2102132736
-1195114496
-522715136
862453760
-775946240
2076180480
-1853882368
1484783616
-1375731712
-1241513984
1409286144
738197504
-2147483648
-2147483648
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

E.g. here https://www.tutorialspoint.com/compile_cpp_online.php

Now to explain why one of them is 0 to begin with:
Because of the values, the sequence of faculties, quickly leaves the value range representable in the chosen data type (note that the number decimal digits does not increase at some point; though the binary digits are the relevant ones).
After that, the values are not really related to the correct values anymore, see them even jumping below zero and back...
... and one of them happens to be 0.

For the "How?" please see the comments (and maybe other, valuable answers).

CodePudding user response:

Short Answer: Your code is not working correctly because it performs 50 factorial, that the answer is 3.04*10^64. This number is greater than the int size, that is 2^31 - 1.

Long answer You can check the problem logging the intermediate answers. This can help you to have some insights about the code situation. Here you can see that the number rotate from positive to negative, that's show the maximum possible multiplication with this code strategy. https://onlinegdb.com/ycnNADKmX

The answer 30414093201713378043612608166064768844377641568960512000000000000

To archive the correct answer to any case of factorial, you need to have some strategy to operate to large numbers. In fact, if you're working a large company, you probably have some library to work with large numbers. In this situation, is very important use this library to keep the code consistent. In other hand, supposing that's an academic homework, you can choose any strategy in the Internet. In this situation I used the strategy that uses string to represent large numbers. You can see the solution here https://www.geeksforgeeks.org/multiply-large-numbers-represented-as-strings

The final program that compute the 50! in the proper manner using the string strategy to represent large numbers you can find here https://onlinegdb.com/XRL9akYKb


PS: I'll put the complete answer here to archive the code for future references.

#include <iostream>
#include<bits/stdc  .h>
using namespace std;

//@see https://www.geeksforgeeks.org/multiply-large-numbers-represented-as-strings/
// Multiplies str1 and str2, and prints result.
string multiply(string num1, string num2)
{
    int len1 = num1.size();
    int len2 = num2.size();
    if (len1 == 0 || len2 == 0)
    return "0";
 
    // will keep the result number in vector
    // in reverse order
    vector<int> result(len1   len2, 0);
 
    // Below two indexes are used to find positions
    // in result.
    int i_n1 = 0;
    int i_n2 = 0;
     
    // Go from right to left in num1
    for (int i=len1-1; i>=0; i--)
    {
        int carry = 0;
        int n1 = num1[i] - '0';
 
        // To shift position to left after every
        // multiplication of a digit in num2
        i_n2 = 0;
         
        // Go from right to left in num2            
        for (int j=len2-1; j>=0; j--)
        {
            // Take current digit of second number
            int n2 = num2[j] - '0';
 
            // Multiply with current digit of first number
            // and add result to previously stored result
            // at current position.
            int sum = n1*n2   result[i_n1   i_n2]   carry;
 
            // Carry for next iteration
            carry = sum/10;
 
            // Store result
            result[i_n1   i_n2] = sum % 10;
 
            i_n2  ;
        }
 
        // store carry in next cell
        if (carry > 0)
            result[i_n1   i_n2]  = carry;
 
        // To shift position to left after every
        // multiplication of a digit in num1.
        i_n1  ;
    }
 
    // ignore '0's from the right
    int i = result.size() - 1;
    while (i>=0 && result[i] == 0)
    i--;
 
    // If all were '0's - means either both or
    // one of num1 or num2 were '0'
    if (i == -1)
    return "0";
 
    // generate the result string
    string s = "";
     
    while (i >= 0)
        s  = std::to_string(result[i--]);
 
    return s;
}
// Calculates the factorial of an inputed number
string fact(int in) {
  string answer = "1";
  for (int i = 2 ; i <= in; i  ) {
    string tmp = std::to_string(i);
    answer = multiply(answer, tmp);
  }
  return answer;
}

int main()
{
  string answer = fact(50);
  cout << answer << endl;
  return 0;
}
  • Related