As many person have already stated, this cannot be directly converted to a tail recursive or an iterative function as floating point function arguments make it difficult to build the result iteratively. However, with a bit of thought the function can be calculated quite efficiently.
First, because all the recursions are summed and end with 1, the function basically calculates the number of paths to the recursion end. For example, for g(5,2), one path would be g(2,5)-> g(2,3) -> g(2,1) (returns 1 here) and an other path g(5,2)-> g(4,2) -> g(3,2) -> g(2,2) -> g(0,2). So to calculate g we need to just calculate the number of the possible paths.
Let's start with the path where we subtract always a from x. Clearly we have only exactly one this kind of path. Next, consider the case where we once we choose the path where we subtract 1 and other times we subtract a, we have floor((x-a)/a) positions to select the 1. Hence, there is floor((x-a)/a) possible paths in this case. In a next iteration, we want to select step 1 twice. There are n*(n-1)/2 combination, where n=floor((x-1-a)/a) and n*(n-1)/2 is the binomial coefficient \binom{n,2} . Next step with three ones there are \binom{n,3} combinations where n is now=floor((x-2-a)/a) etc.
If you pre-calculate the binomial coefficient the algorithm is O(x), hence it probably could also calculate g(sqrt(10000019),10000019). However, the largest native c++ integer type (unsigned long long) overflows already around g(sqrt(500),500). You can use long double to get an approximate value for slightly larger input. Alternatively you can use boost Multiprecision Library to get more digits, but I assume you will run out of memory before you get the answer to g(sqrt(10000019),10000019).
The source code with an overflow check to calculate g()
#include <iostream>
#include <vector>
#include <limits>
#include <algorithm>
#include <cstdlib>
unsigned long long binomial(unsigned int n, unsigned int m) {
if (n - m < m) m = n - m;
std::vector<unsigned long long>bc(m+1, 0);
bc[0] = 1;
for (unsigned int i = 0;i <= n;++i) {
for (unsigned int j = std::min(i, m);j > 0;j--) {
if (std::numeric_limits<unsigned long long>::max()-bc[j-1] < bc[j]) {
std::cout << "Error: too large binomial coefficient(" << n << "," << m << ")" << std::endl;
exit(1);
}
bc[j] += bc[j - 1];
}
}
return bc[m];
}
unsigned long long g(double a, double x) {
unsigned long long r = 1;
int n = 0;
for (int i = static_cast<int>(x);i >= a;--i) {
++n;
int m = static_cast<int>((i - a) / a);
unsigned long long b = binomial(m + n, n);
if (std::numeric_limits<unsigned long long>::max() - b < r) {
std::cout << "Error: too large sum " << b << "+" << r << std::endl;
exit(1);
}
r += b;
}
return r;
}
int main(){
std::cout << g(sqrt(90), 90) << std::endl;
std::cout << g(sqrt(10000019), 10000019) << std::endl;
}