The number D computed by the following polynomial formula

``````D=(pow(i,5.)/120)-(pow(i,4.)/12)+(23*pow(i,3.)/24)-(83*i*i/12)+(571*i/30)
``````

should always be an integer, when i=1,2,3,4,5,....
However, for some i values, each separate term may not be an integer, but when putting together (with additions and subtractions) in the above formula, any non-integer parts would be "cancelled out", and the result should be precisely an integer.

The problem is, using this formula directly, the resulting numbers are sometimes inaccurate (for some i values), with the last digit 1 off (+1 or -1) from what it should be.

So I modified the code as follows, which gets better (less errors), but still not 100% accurate (never mind the long long type--it's for when i gets large):

``````       long long v=pow(i,5.), w=pow(i,4.), x=23*pow(i,3.), y=83*i*i, z=571*i, vv,ww,xx,yy,zz;
if (v%120!=0)
{
if (v/120.<((floor(v/120.)+ceil(v/120.))/2.))
vv=floor(v/120.);
else
vv=ceil(v/120.);
}
else
vv=v/120;
if (w%12!=0)
{
if (w/12.<((floor(w/12.)+ceil(w/12.))/2.))
ww=floor(w/12.);
else
ww=ceil(w/12.);
}
else
ww=w/12;
if (x%24!=0)
{
if (x/24.<((floor(x/24.)+ceil(x/24.))/2.))
xx=floor(x/24.);
else
xx=ceil(x/24.);
}
else
xx=x/24;
if (y%12!=0)
{
if (y/12.<((floor(y/12.)+ceil(y/12.))/2.))
yy=floor(y/12.);
else
yy=ceil(y/12.);
}
else
yy=y/12;
if (z%30!=0)
{
if (z/30.<((floor(z/30.)+ceil(z/30.))/2.))
zz=floor(z/30.);
else
zz=ceil(z/30.);
}
else
zz=z/30;

long long D=v/120-w/12+x/24-y/12+z/30-16;
``````

Hope it's clear to you the idea behind this code: it means to "cancel out" non-integer parts by truncating or rounding up the non-integer term according to whether the digit after the decimal point is less than 5 or not.

It still has errors (e.g. when i=6, D should be 29, but the output is 28; when i=12, D should be 1234, but the output is 1233; etc.).

I just realized the problem is probably when there are two terms both being exactly __.5 (the digit after the decimal point is 5), in which case both would be rounded up (ceil) to 1 by my program above, so when adding them the last digit would become 1+1=2, when it should be .5+.5=1.
When thinking more, it seem quite complicated even if to add more if...else... Any way to solve the problem?

Thanks in advance!

## Recommended Answers

Observe that you are calculating factorials as the division : So the quickest route is to remove the common factor.
E.g

``````int calc(const int I)
{
int sum(0);
int x(I);
//   D=(pow(i,5.)/120)-(pow(i,4.)/12)+(23*pow(i,3.)/24)-(83*i*i/12)+(571*i/30)
sum+=(120/30)*571*x;
x*=I;
sum-=(120/12)*83*x;
x*=I;
sum+=(120/24)*23*x;
x*=I;
sum-=(120/12)*x;
x*=I;
sum+=x;

return sum/120;
}
``````

Note that …

## All 3 Replies

deleted (added in original post)

Observe that you are calculating factorials as the division : So the quickest route is to remove the common factor.
E.g

``````int calc(const int I)
{
int sum(0);
int x(I);
//   D=(pow(i,5.)/120)-(pow(i,4.)/12)+(23*pow(i,3.)/24)-(83*i*i/12)+(571*i/30)
sum+=(120/30)*571*x;
x*=I;
sum-=(120/12)*83*x;
x*=I;
sum+=(120/24)*23*x;
x*=I;
sum-=(120/12)*x;
x*=I;
sum+=x;

return sum/120;
}
``````

Note that I have used the 120 as a factor and you could put it into a constant etc. but it shows the basic trick.

Typcially I would have used an array like this:

``````int calc(const int I)
{
const int topFactor[]={571,-83,23,-1,1};
const int baseFactor[]={30,12,24,12,120}
const int commonF(120);

int sum(0);
int x(1)
for(int j=0;j<5;j++)
{
x*=I;
sum+= topFactor[j]*(commonF/baseFactor[j]);
}
return sum/commonF;
}
``````

Finally the value D that you are calculating is not an interger function, and you would get rounding effects.

I am assuming that I understood the question correctly, if not please say!

Thanks for the reply! I tried your first suggestion by multiplying each term by 120 as double type, then putting them in the D forumula (adding or subtracting) as long long type, then taking D/=120 as the result. It achieved the desired result---at least for the first 100 terms (probably for the rest), it's accurate! Looking back at my tedious floor/ceil approach it was so awful ;). I'll work through your second method...

This problem really comes down to the requirement of pow having at least one non-integer parameter. Wonder why such a requirement...

Many thanks for taking your time reading and helping! :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of 1.21 million developers, IT pros, digital marketers, and technology enthusiasts learning and sharing knowledge.