std::_throw_out_of_range 无处不在
std::_throw_out_of_range occurs from nowhere
我绝对是 C++ 的初学者。字面上地。才过了一个星期。
今天我在写一个程序来测试需要多少次迭代才能使某个数字回文。
这是代码:
#include <iostream>
#include <string>
#include <algorithm>
/* This program calculates the steps needed
to make a certain number palindromic.
It is designed to output the values for
numbers 1 to 1000
*/
using namespace std;
class number
{
public:
string value;
void reverse();
};
void number::reverse()
{
std::reverse(value.begin(),value.end());
}
void palindrome(number num)
{
string n=num.value;
number reversenum, numsum, numsumreverse;
reversenum=num;
reversenum.reverse();
numsum.value=num.value;
numsumreverse.value=numsum.value;
numsumreverse.reverse();
int i=0;
while (numsum.value.compare(numsumreverse.value) !=0)
{
reversenum=num;
reversenum.reverse();
numsum.value=to_string(stoll(num.value,0,10)+stoll(reversenum.value,0,10));
numsumreverse.value=numsum.value;
numsumreverse.reverse();
num.value=numsum.value;
i++;
}
cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num.value << endl;
}
int main()
{
number temp;
int i;
for (i=1; i<1001; i++)
{
temp.value=to_string(i);
palindrome(temp);
}
return 0;
}
对于 195 以内的数字,它会顺利进行。但是,如果是 196,我会收到错误消息。
它说:
terminate called after throwing an instance of 'std::out_of_range'
what(): stoll
我不知道该怎么办。我尝试从 196
开始,但错误仍然存在。任何帮助将不胜感激。 :)
更新:这次我尝试使用 ttmath 库来完成。但是啊!它再次停在 195,甚至不报告错误!我可能正在做一些愚蠢的事情。如有任何意见,我们将不胜感激。这是更新后的代码:
#include <iostream>
#include <string>
#include <algorithm>
#include <ttmath/ttmath.h>
/* This program calculates the steps needed
to make a certain number palindromic.
It is designed to output the values for
numbers 1 to 1000
*/
using namespace std;
class number
{
public:
string value;
void reverse();
};
void number::reverse()
{
std::reverse(value.begin(),value.end());
}
template <typename NumTy>
string String(const NumTy& Num)
{
stringstream StrStream;
StrStream << Num;
return (StrStream.str());
}
void palindrome(number num)
{
string n=num.value;
number reversenum, numsum, numsumreverse;
reversenum=num;
reversenum.reverse();
numsum.value=num.value;
numsumreverse.value=numsum.value;
numsumreverse.reverse();
ttmath::UInt<100> tempsum, numint, reversenumint;
int i=0;
while (numsum.value.compare(numsumreverse.value) !=0)
{
reversenum=num;
reversenum.reverse();
numint=num.value;
reversenumint=reversenum.value;
tempsum=numint+reversenumint;
numsum.value=String<ttmath::UInt<100> >(tempsum);
numsumreverse.value=numsum.value;
numsumreverse.reverse();
num.value=numsum.value;
i++;
}
cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num.value << endl;
}
int main()
{
number temp;
int i;
for (i=196; i<1001; i++)
{
temp.value=to_string(i);
palindrome(temp);
}
return 0;
}
更新:已解决。一些研究表明 196 可能是 Lychrel Number。在暗示 ttmath 库后我得到的结果只是让我确信我的算法有效。我已经尝试了所有高达 10000 的数字,它给出了完美的结果。这是最终代码:
#include <iostream>
#include <string>
#include <algorithm>
#include <ttmath/ttmath.h>
#include <limits>
/* This program calculates the steps needed
to make a certain number palindromic.
It is designed to output the values for
numbers inside a desired range
*/
using namespace std;
string LychrelList;
int LychrelCount=0;
class number
{
public:
string value;
void reverse();
};
void number::reverse()
{
std::reverse(value.begin(),value.end());
}
template <typename NumTy>
string String(const NumTy& Num)
{
stringstream StrStream;
StrStream << Num;
return (StrStream.str());
}
void palindrome(number num)
{
string n=num.value;
number reversenum, numsum, numsumreverse;
reversenum=num;
reversenum.reverse();
numsum.value=num.value;
numsumreverse.value=numsum.value;
numsumreverse.reverse();
ttmath::UInt<100> tempsum, numint, reversenumint;
int i=0;
while ((numsum.value.compare(numsumreverse.value) !=0) && i<200)
{
reversenum=num;
reversenum.reverse();
numint=num.value;
reversenumint=reversenum.value;
tempsum=numint+reversenumint;
numsum.value=String<ttmath::UInt<100> >(tempsum);
numsumreverse.value=numsum.value;
numsumreverse.reverse();
num.value=numsum.value;
i++;
}
if (i<200) cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num.value << endl;
else
{
cout << "A solution for " << n << " could not be found!!!" << endl;
LychrelList=LychrelList+n+" ";
LychrelCount++;
}
}
int main()
{
cout << "From where to start?" << endl << ">";
int lbd,ubd;
cin >> lbd;
cout << endl << "And where to stop?" << endl <<">";
cin >> ubd;
cout << endl;
number temp;
int i;
for (i=lbd; i<=ubd; i++)
{
temp.value=to_string(i);
palindrome(temp);
}
if (LychrelList.compare("") !=0) cout << "The possible Lychrel numbers found in the range are:" << endl << LychrelList << endl << "Total - " << LychrelCount;
cout << endl << endl << "Press ENTER to end the program...";
cin.ignore(numeric_limits<streamsize>::max(), '\n');
string s;
getline(cin,s);
cout << "Thanks for using!";
return 0;
}
这是一个非常棒的社区。特别感谢 Marco A。 :)
再次更新:我设计了我自己的 add() 函数来减少程序对外部库的依赖。它导致更小的可执行文件和更快的性能。这是代码:
#include <iostream>
#include <string>
#include <algorithm>
#include <limits>
/* This program calculates the steps needed
to make a certain number palindromic.
It is designed to output the values for
numbers inside a desired range
*/
using namespace std;
string LychrelList;
int LychrelCount=0;
string add(string sA, string sB)
{
int iTemp=0;
string sAns;
int k=sA.length()-sB.length();
int i;
if (k>0){for (i=0;i<k;i++) {sB="0"+sB;}}
if (k<0) {for (i=0;i<-k;i++) {sA="0"+sA;}}
for (i=sA.length()-1;i>=0;i--)
{
iTemp+=sA[i]+sB[i]-96;
if (iTemp>9)
{
sAns=to_string(iTemp%10)+sAns;
iTemp/=10;
}
else
{
sAns=to_string(iTemp)+sAns;
iTemp=0;
}
}
if (iTemp>0) {sAns=to_string(iTemp)+sAns;}
return sAns;
}
void palindrome(string num)
{
string n=num;
string reversenum, numsum, numsumreverse;
numsum=num;
numsumreverse=numsum;
reverse(numsumreverse.begin(),numsumreverse.end());
int i=0;
while ((numsum.compare(numsumreverse) !=0) && i<200)
{
reversenum=num;
reverse(reversenum.begin(),reversenum.end());
numsum=add(num,reversenum);
numsumreverse=numsum;
reverse(numsumreverse.begin(),numsumreverse.end());
num=numsum;
i++;
}
if (i<200) cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num << endl;
else
{
cout << "A solution for " << n << " could not be found!!!" << endl;
LychrelList=LychrelList+n+" ";
LychrelCount++;
}
}
int main()
{
cout << "From where to start?" << endl << ">";
int lbd,ubd;
cin >> lbd;
cout << endl << "And where to stop?" << endl <<">";
cin >> ubd;
cout << endl;
string temp;
int i;
for (i=lbd; i<=ubd; i++)
{
temp=to_string(i);
palindrome(temp);
}
if (LychrelList.compare("") !=0) cout << "The possible Lychrel numbers found in the range are:" << endl << LychrelList << endl << "Total - " << LychrelCount;
cout << endl << endl << "Press ENTER to end the program...";
cin.ignore(numeric_limits<streamsize>::max(), '\n');
string s;
getline(cin,s);
cout <<endl << "Thanks for using!";
return 0;
}
你们帮了我很多,让我找到了自己的路。感谢大家。 :)
你 溢出 long long
因为 num.value
和 reversenum.value
的最后两个有效值是 7197630720180367016 和 6107630810270367917,它们加在一起, 远远超过 long long
的最大大小(在我的机器上为 9223372036854775807)。这将产生负值并破坏您对 stoll
的下一次调用
std::out_of_range is thrown if the converted value would fall out of the range of the result type or if the underlying function (std::strtol or std::strtoll) sets errno to ERANGE.
- 如果您想要获得下一个最小的回文,您应该使用另一种方法,例如I explained here。
你可以在这里找到 Live Example
- 如果您更喜欢 to/must 继续您的方法,您应该在字符串上手动添加或使用 bigint 库(再次查看 here 并根据自己的喜好修改
plusOne()
函数)
来自http://www.cplusplus.com/reference/string/stoll/
If the value read is out of the range of representable values by a long long, an out_of_range exception is thrown.
ll 数据类型无法处理字符串长度。我的调试器告诉我 196 次中断值
std::stoll (__str=\"9605805010994805921-\", __idx=0x0, __base=10)
long long太小了。
您可能希望对字符串本身进行加法运算,而不求助于数字类型。
我绝对是 C++ 的初学者。字面上地。才过了一个星期。 今天我在写一个程序来测试需要多少次迭代才能使某个数字回文。 这是代码:
#include <iostream>
#include <string>
#include <algorithm>
/* This program calculates the steps needed
to make a certain number palindromic.
It is designed to output the values for
numbers 1 to 1000
*/
using namespace std;
class number
{
public:
string value;
void reverse();
};
void number::reverse()
{
std::reverse(value.begin(),value.end());
}
void palindrome(number num)
{
string n=num.value;
number reversenum, numsum, numsumreverse;
reversenum=num;
reversenum.reverse();
numsum.value=num.value;
numsumreverse.value=numsum.value;
numsumreverse.reverse();
int i=0;
while (numsum.value.compare(numsumreverse.value) !=0)
{
reversenum=num;
reversenum.reverse();
numsum.value=to_string(stoll(num.value,0,10)+stoll(reversenum.value,0,10));
numsumreverse.value=numsum.value;
numsumreverse.reverse();
num.value=numsum.value;
i++;
}
cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num.value << endl;
}
int main()
{
number temp;
int i;
for (i=1; i<1001; i++)
{
temp.value=to_string(i);
palindrome(temp);
}
return 0;
}
对于 195 以内的数字,它会顺利进行。但是,如果是 196,我会收到错误消息。 它说:
terminate called after throwing an instance of 'std::out_of_range' what(): stoll
我不知道该怎么办。我尝试从 196
开始,但错误仍然存在。任何帮助将不胜感激。 :)
更新:这次我尝试使用 ttmath 库来完成。但是啊!它再次停在 195,甚至不报告错误!我可能正在做一些愚蠢的事情。如有任何意见,我们将不胜感激。这是更新后的代码:
#include <iostream>
#include <string>
#include <algorithm>
#include <ttmath/ttmath.h>
/* This program calculates the steps needed
to make a certain number palindromic.
It is designed to output the values for
numbers 1 to 1000
*/
using namespace std;
class number
{
public:
string value;
void reverse();
};
void number::reverse()
{
std::reverse(value.begin(),value.end());
}
template <typename NumTy>
string String(const NumTy& Num)
{
stringstream StrStream;
StrStream << Num;
return (StrStream.str());
}
void palindrome(number num)
{
string n=num.value;
number reversenum, numsum, numsumreverse;
reversenum=num;
reversenum.reverse();
numsum.value=num.value;
numsumreverse.value=numsum.value;
numsumreverse.reverse();
ttmath::UInt<100> tempsum, numint, reversenumint;
int i=0;
while (numsum.value.compare(numsumreverse.value) !=0)
{
reversenum=num;
reversenum.reverse();
numint=num.value;
reversenumint=reversenum.value;
tempsum=numint+reversenumint;
numsum.value=String<ttmath::UInt<100> >(tempsum);
numsumreverse.value=numsum.value;
numsumreverse.reverse();
num.value=numsum.value;
i++;
}
cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num.value << endl;
}
int main()
{
number temp;
int i;
for (i=196; i<1001; i++)
{
temp.value=to_string(i);
palindrome(temp);
}
return 0;
}
更新:已解决。一些研究表明 196 可能是 Lychrel Number。在暗示 ttmath 库后我得到的结果只是让我确信我的算法有效。我已经尝试了所有高达 10000 的数字,它给出了完美的结果。这是最终代码:
#include <iostream>
#include <string>
#include <algorithm>
#include <ttmath/ttmath.h>
#include <limits>
/* This program calculates the steps needed
to make a certain number palindromic.
It is designed to output the values for
numbers inside a desired range
*/
using namespace std;
string LychrelList;
int LychrelCount=0;
class number
{
public:
string value;
void reverse();
};
void number::reverse()
{
std::reverse(value.begin(),value.end());
}
template <typename NumTy>
string String(const NumTy& Num)
{
stringstream StrStream;
StrStream << Num;
return (StrStream.str());
}
void palindrome(number num)
{
string n=num.value;
number reversenum, numsum, numsumreverse;
reversenum=num;
reversenum.reverse();
numsum.value=num.value;
numsumreverse.value=numsum.value;
numsumreverse.reverse();
ttmath::UInt<100> tempsum, numint, reversenumint;
int i=0;
while ((numsum.value.compare(numsumreverse.value) !=0) && i<200)
{
reversenum=num;
reversenum.reverse();
numint=num.value;
reversenumint=reversenum.value;
tempsum=numint+reversenumint;
numsum.value=String<ttmath::UInt<100> >(tempsum);
numsumreverse.value=numsum.value;
numsumreverse.reverse();
num.value=numsum.value;
i++;
}
if (i<200) cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num.value << endl;
else
{
cout << "A solution for " << n << " could not be found!!!" << endl;
LychrelList=LychrelList+n+" ";
LychrelCount++;
}
}
int main()
{
cout << "From where to start?" << endl << ">";
int lbd,ubd;
cin >> lbd;
cout << endl << "And where to stop?" << endl <<">";
cin >> ubd;
cout << endl;
number temp;
int i;
for (i=lbd; i<=ubd; i++)
{
temp.value=to_string(i);
palindrome(temp);
}
if (LychrelList.compare("") !=0) cout << "The possible Lychrel numbers found in the range are:" << endl << LychrelList << endl << "Total - " << LychrelCount;
cout << endl << endl << "Press ENTER to end the program...";
cin.ignore(numeric_limits<streamsize>::max(), '\n');
string s;
getline(cin,s);
cout << "Thanks for using!";
return 0;
}
这是一个非常棒的社区。特别感谢 Marco A。 :)
再次更新:我设计了我自己的 add() 函数来减少程序对外部库的依赖。它导致更小的可执行文件和更快的性能。这是代码:
#include <iostream>
#include <string>
#include <algorithm>
#include <limits>
/* This program calculates the steps needed
to make a certain number palindromic.
It is designed to output the values for
numbers inside a desired range
*/
using namespace std;
string LychrelList;
int LychrelCount=0;
string add(string sA, string sB)
{
int iTemp=0;
string sAns;
int k=sA.length()-sB.length();
int i;
if (k>0){for (i=0;i<k;i++) {sB="0"+sB;}}
if (k<0) {for (i=0;i<-k;i++) {sA="0"+sA;}}
for (i=sA.length()-1;i>=0;i--)
{
iTemp+=sA[i]+sB[i]-96;
if (iTemp>9)
{
sAns=to_string(iTemp%10)+sAns;
iTemp/=10;
}
else
{
sAns=to_string(iTemp)+sAns;
iTemp=0;
}
}
if (iTemp>0) {sAns=to_string(iTemp)+sAns;}
return sAns;
}
void palindrome(string num)
{
string n=num;
string reversenum, numsum, numsumreverse;
numsum=num;
numsumreverse=numsum;
reverse(numsumreverse.begin(),numsumreverse.end());
int i=0;
while ((numsum.compare(numsumreverse) !=0) && i<200)
{
reversenum=num;
reverse(reversenum.begin(),reversenum.end());
numsum=add(num,reversenum);
numsumreverse=numsum;
reverse(numsumreverse.begin(),numsumreverse.end());
num=numsum;
i++;
}
if (i<200) cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num << endl;
else
{
cout << "A solution for " << n << " could not be found!!!" << endl;
LychrelList=LychrelList+n+" ";
LychrelCount++;
}
}
int main()
{
cout << "From where to start?" << endl << ">";
int lbd,ubd;
cin >> lbd;
cout << endl << "And where to stop?" << endl <<">";
cin >> ubd;
cout << endl;
string temp;
int i;
for (i=lbd; i<=ubd; i++)
{
temp=to_string(i);
palindrome(temp);
}
if (LychrelList.compare("") !=0) cout << "The possible Lychrel numbers found in the range are:" << endl << LychrelList << endl << "Total - " << LychrelCount;
cout << endl << endl << "Press ENTER to end the program...";
cin.ignore(numeric_limits<streamsize>::max(), '\n');
string s;
getline(cin,s);
cout <<endl << "Thanks for using!";
return 0;
}
你们帮了我很多,让我找到了自己的路。感谢大家。 :)
你 溢出 long long
因为 num.value
和 reversenum.value
的最后两个有效值是 7197630720180367016 和 6107630810270367917,它们加在一起, 远远超过 long long
的最大大小(在我的机器上为 9223372036854775807)。这将产生负值并破坏您对 stoll
std::out_of_range is thrown if the converted value would fall out of the range of the result type or if the underlying function (std::strtol or std::strtoll) sets errno to ERANGE.
- 如果您想要获得下一个最小的回文,您应该使用另一种方法,例如I explained here。
你可以在这里找到 Live Example
- 如果您更喜欢 to/must 继续您的方法,您应该在字符串上手动添加或使用 bigint 库(再次查看 here 并根据自己的喜好修改
plusOne()
函数)
来自http://www.cplusplus.com/reference/string/stoll/
If the value read is out of the range of representable values by a long long, an out_of_range exception is thrown.
ll 数据类型无法处理字符串长度。我的调试器告诉我 196 次中断值
std::stoll (__str=\"9605805010994805921-\", __idx=0x0, __base=10)
long long太小了。
您可能希望对字符串本身进行加法运算,而不求助于数字类型。