为什么 for 循环对于 1 到 50 的简单乘法不能正常工作?
why for loop is not work correctly for a simple multiplication numbers 1 to 50?
代码:
#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;
}
结果:
0
...Program finished with exit code 0
Press ENTER to exit console.
当我 运行 此代码在 online c++ compiler 中时, 它在控制台 中显示为零 (0)。为什么?
我会专门回答“为什么?”这个问题。而不是评论中添加的“如何?”。
你得到结果 0,因为 answer
的中间值之一是 0 并且与它相乘将保持 0。
这是中间值(我通过将您的输出移到循环中找到它们。):
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
例如这里 https://www.tutorialspoint.com/compile_cpp_online.php
现在解释为什么其中一个是0开头:
由于值的原因,院系的序列很快离开了所选数据类型中可表示的值范围(请注意,小数位数在某些时候不会增加;尽管二进制数字是相关的)。
在那之后,这些值不再与正确的值真正相关,看到它们甚至跳到零以下并返回...
...其中之一恰好是 0.
对于“如何?”请查看评论(也许还有其他有价值的答案)。
简答:
您的代码无法正常工作,因为它执行 50 个阶乘,答案是 3.04*10^64。此数字大于 int 大小,即 2^31 - 1.
长答案
您可以检查记录中间答案的问题。这可以帮助您对代码情况有一些了解。在这里您可以看到数字从正数旋转到负数,这显示了此代码策略的最大可能乘法。
https://onlinegdb.com/ycnNADKmX
答案
30414093201713378043612608166064768844377641568960512000000000000
要存档任何阶乘案例的正确答案,您需要有一些策略来操作大数。
事实上,如果你在一家大公司工作,你可能有一些库来处理大量数据。在这种情况下,使用这个库来保持代码的一致性非常重要。
另一方面,假设这是一个学术作业,你可以选择互联网上的任何策略。在这种情况下,我使用了使用字符串来表示大数字的策略。您可以在此处查看解决方案 https://www.geeksforgeeks.org/multiply-large-numbers-represented-as-strings
计算50的最终程序!以正确的方式使用字符串策略来表示大数,您可以在此处找到 https://onlinegdb.com/XRL9akYKb
PS:我会把完整的答案放在这里,以存档代码以备将来参考。
#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;
}
代码:
#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;
}
结果:
0
...Program finished with exit code 0
Press ENTER to exit console.
当我 运行 此代码在 online c++ compiler 中时, 它在控制台 中显示为零 (0)。为什么?
我会专门回答“为什么?”这个问题。而不是评论中添加的“如何?”。
你得到结果 0,因为 answer
的中间值之一是 0 并且与它相乘将保持 0。
这是中间值(我通过将您的输出移到循环中找到它们。):
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
例如这里 https://www.tutorialspoint.com/compile_cpp_online.php
现在解释为什么其中一个是0开头:
由于值的原因,院系的序列很快离开了所选数据类型中可表示的值范围(请注意,小数位数在某些时候不会增加;尽管二进制数字是相关的)。
在那之后,这些值不再与正确的值真正相关,看到它们甚至跳到零以下并返回...
...其中之一恰好是 0.
对于“如何?”请查看评论(也许还有其他有价值的答案)。
简答: 您的代码无法正常工作,因为它执行 50 个阶乘,答案是 3.04*10^64。此数字大于 int 大小,即 2^31 - 1.
长答案 您可以检查记录中间答案的问题。这可以帮助您对代码情况有一些了解。在这里您可以看到数字从正数旋转到负数,这显示了此代码策略的最大可能乘法。 https://onlinegdb.com/ycnNADKmX
答案 30414093201713378043612608166064768844377641568960512000000000000
要存档任何阶乘案例的正确答案,您需要有一些策略来操作大数。 事实上,如果你在一家大公司工作,你可能有一些库来处理大量数据。在这种情况下,使用这个库来保持代码的一致性非常重要。 另一方面,假设这是一个学术作业,你可以选择互联网上的任何策略。在这种情况下,我使用了使用字符串来表示大数字的策略。您可以在此处查看解决方案 https://www.geeksforgeeks.org/multiply-large-numbers-represented-as-strings
计算50的最终程序!以正确的方式使用字符串策略来表示大数,您可以在此处找到 https://onlinegdb.com/XRL9akYKb
PS:我会把完整的答案放在这里,以存档代码以备将来参考。
#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;
}