Here's the code: <!-- language: lang-cpp --> #include <boost/multiprecision/cpp_dec_float.hpp> #include <boost/lexical_cast.hpp> #include <boost/algorithm/string.hpp> #include <iostream> #include <cmath> #include <iomanip> #include <limits> #include <exception> const int PRECISION = 100; typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<PRECISION> > arbFloat; // Prototypes bool isStringValid(const std::string & str); bool isNumberValid(const arbFloat & x); inline std::string resizeArbtoString(const arbFloat & x); int main(){ arbFloat zeta = 0.0; std::cout << "\u03b6(s), s = "; std::string inputStr; std::getline(std::cin, inputStr); if(!isStringValid(inputStr)) return 2; arbFloat input = static_cast<arbFloat>(inputStr); if(!isNumberValid(input)) return 3; std::cout << std::setprecision(PRECISION); int i = 1; if(input == 0) { zeta = -0.5; } else { std::string preComp, postComp; std::cout << "Convergence:\n"; do { preComp = resizeArbtoString(zeta); zeta += pow(i, -input); postComp = resizeArbtoString(zeta); std::cout << '\t' + preComp + '\n'; i++; } while(preComp != postComp); } std::cout << "\n\u03b6(" + inputStr + ") = " << zeta << "\nAfter " << i << " iterations"; return 0; } // Check input bool isStringValid(const std::string & str){ // Check if string contains spaces if(std::count(str.begin(), str.end(), ' ') > 0){ std::cout << "\nError: Input contains spaces\n"; return false; } // Check if string contains multiple . if(std::count(str.begin(), str.end(), '.') > 1){ std::cout << "\nError: Input contains multiple decimal marks\n"; return false; } // Check if NaN or Out of bounds (due to parsing failure) try{ boost::lexical_cast<arbFloat>(str); } catch(std::runtime_error){ std::cout << "\nError: Unable to parse (value too large or incorrect number type)\n"; return false; } catch(...){ std::cout << "\nError: Input is NaN\n"; return false; } // Check if intentional NaN if(boost::icontains(str, "nan")){ std::cout << "\nError: Intentional NaN\n"; return false; } return true; } // Check number bool isNumberValid(const arbFloat & x){ // Range check if(x == std::numeric_limits<arbFloat>::infinity()){ std::cout << "\nError: Out of bounds\n"; return false; } if(x == 1){ std::cout << "\nError: Complex Infinity\n"; return false; } if(x < 2){ std::cout << "\nError: Does not converge (unsupported)\n"; return false; } return true; } inline std::string resizeArbtoString(const arbFloat & x){ std::string resizedStr = static_cast<std::string>(x); resizedStr.resize(PRECISION + 2); return resizedStr; } #Explanation# This is used to calculate the [Riemann Zeta Function][1] for **real** numbers that are **greater than 2** (other than zero). **Smaller values will take much longer. This is a result of the algorithm I use for approximating the Riemann Zeta function, not due to implementation.** Likewise, larger values are much faster. If a larger value (around 500+) is entered, the precision of 100 digits is exceeded (it returns 1, but there are still digits past all those zeroes). I am using three [Boost libraries][2]: multi-precision, lexical cast, and string algorithms. First I initialize an arbitrary float with the precision of `100` (the value in the code will be manually changed occasionally). I am using function prototypes. First I define the variable `zeta` to be zero. Then I get the user input (example output is below). I then check if it is a valid string that will convert easily to an `arbFloat` by using the `isStringValid` function. I use a string at first to catch things like multiple periods or spaces (and so on), which result in differing behavior. I then convert it to an `arbFloat`, and check if that number is valid using the `isNumberValid` function. Next I set the output precision. Inside of the if-else statement, I do the calculations. Inside of the else portion, I first convert the initial value of `zeta` to a string using the `resizeArbtoString` function. The string is being resized to `PRECISION + 2` to account for the number before the decimal mark, and the decimal mark itself. I then do the actual calculations. Next, the resulting value of `zeta` is converted to a string using the same technique as before. The do-while loop checks if the strings are the same before and after calculations (if they are, it would result in an endless loop anyways). Finally the value of `zeta` is printed along with the number of iterations. #Example output# <!-- language: lang-none --> ζ(s), s = 100 Convergence: 0 1 1.0000000000000000000000000000007888609052210118054117285652827862296732064351090230047702789306640624 1.0000000000000000000000000000007888609052210118073520537827654190672617124639136733859843956171621636 1.0000000000000000000000000000007888609052210118073520537827660413687894985780843877923897736295862226 1.0000000000000000000000000000007888609052210118073520537827660413687896253431444106153299232999067602 1.0000000000000000000000000000007888609052210118073520537827660413687896253431459412620374098062482047 1.0000000000000000000000000000007888609052210118073520537827660413687896253431459412623465788470572268 1.0000000000000000000000000000007888609052210118073520537827660413687896253431459412623465793379665733 1.0000000000000000000000000000007888609052210118073520537827660413687896253431459412623465793379703381 1.0000000000000000000000000000007888609052210118073520537827660413687896253431459412623465793379703382 ζ(100) = 1.000000000000000000000000000000788860905221011807352053782766041368789625343145941262346579337970338 After 12 iterations RUN SUCCESSFUL (total time: 3s) --- Am I doing something inefficiently? **How can I improve this code?** [1]: https://en.wikipedia.org/wiki/Riemann_zeta_function [2]: http://www.boost.org/