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!

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 developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.