0

This program will take 3 interger values a, b and N. The program will find the sum of the decimals from division value of (a/b) up to N numbers. For example: example of input and output

enter image description here

Sorry my technical english wasn't very good, my program (in C) should do the following:

  1. It takes values of a, b, and N
  2. It perform division of a and b
  3. It takes the division in float and separate it into integer value and fractional part
  4. It add to sum of fractional part rounded down
  5. It update the base division value by multiply by 10
  6. It update conditions of the loop of n=N
  7. Output in printf.

However, my program only give the right value up till a=252525 b=99 N=33 output=171 which i think is wrong. Please help me correct my algorithm.

#include<stdio.h>

int main()
{
    unsigned int a, b, N; 
    int n;
    double x,inte, frac;  //x is output, integer part, fractional part 
    long double div; //division value of a/b
    printf("Enter so nguyen duong a : \n"); scanf("%d",&a);
    printf("Enter so nguyen duong b : \n"); scanf("%d",&b);
    printf("Enter so nguyen duong N : \n"); scanf("%d",&N);
    div = (long double) a / (long double)b;
    x = 0;
    for(n=0;n<N;n++)
    {
    frac = modf(div,&inte);  //perform separating integer and fractional part of division
    x = x + (int)floor(frac*10);  //round down the fractional part of division
    div=frac*10;
    }
    printf("a / b = %.20f\n",(double) a / (double)b);
    printf ("tong cua %i chu so sau dau phay la = %.0f\n",N,x);
    
}
phatx88
  • 25
  • 4
  • Why call a `double` function with a `long double` `modf()`? `modfl()` would provide a `long double` fraction. Else why not simply do a `double` divide? – chux - Reinstate Monica Jul 08 '20 at 02:44
  • 1
    For large values of N, the technique you're using won't work. For example, in test 5, the correct division result is 336.666666... with the 6s repeating forever. But the result in `div` is actually 336.6666666666666666574148... So your code would only work for N up to 16. – user3386109 Jul 08 '20 at 02:55
  • 1
    There's no easy way to fix your program. I think you need to implement division using the grade school long division algorithm, and look for the repeating pattern. Or just keep dividing until you've computed enough digits. – user3386109 Jul 08 '20 at 02:59
  • Either the long division algorithm must be implemented or an arbitrary precision arithmetic library must be used to solve this problem for arbitrary integers. – M. Nejat Aydin Jul 08 '20 at 04:58
  • Yup, I simply do not know or try that many functions. It's good to know that i can simply use modfl() instead of modf. – phatx88 Jul 08 '20 at 06:03

1 Answers1

1

It would be simpler (and accurate, as @user3386109 pointed out, floating point arithmetic will begin to loose precision as the number of decimals increase) if you devise your own "integer division function"; something like below (the function divide).

edit: Tested for a = 252525, b = 99, N = 33; output was 199 which seem OK to me. The fraction part is like ".7575757575..."; the first 32 digits add up to 16 * 12 = 192, adding the last "7" (33rd digit) makes 199.

void divide(
    unsigned int a,
    unsigned int b,
    unsigned int *d,
    unsigned int *r
) {
    *d = a / b;
    *r = a - *d * b;
    return;
}

unsigned int sum(
    unsigned int a,
    unsigned int b,
    unsigned int n
) {
    unsigned int k = 0;
    unsigned int d = 0; // division
    unsigned int r = 0; // remainder
    unsigned int s = 0; // sum

    // do an intial integer division to reach the decimal part
    divide(a, b, &d, &r);

    while (k < n) {
        a = r * 10;
        divide(a, b, &d, &r);
        s += d;
        k++;
    }

    return s;
}

int main() {
    unsigned int a = 20;
    unsigned int b = 13;
    unsigned int n = 4;
    printf("first %u decimal sum of division %u / %u = %u\n", n, a, b, sum(a, b, n));

    a = 25;
    b = 3;
    n = 5;
    printf("first %u decimal sum of division %u / %u = %u\n", n, a, b, sum(a, b, n));

    a = 4;
    b = 2;
    n = 10;
    printf("first %u decimal sum of division %u / %u = %u\n", n, a, b, sum(a, b, n));

    a = 2020;
    b = 21;
    n = 6;
    printf("first %u decimal sum of division %u / %u = %u\n", n, a, b, sum(a, b, n));

    return 0;
}
ssd
  • 2,080
  • 4
  • 15
  • 29
  • I'm not quite grasp the math behind the division of two integer numbers. I hope some one can prefer me to a link where it is explained better. From what i understand unsigned int a=20, b=13, so 20/13 = 1? How does it work? – phatx88 Jul 08 '20 at 06:25
  • The function divides 20 by 13 giving division 1 and remainder 7. The function, having parameters d & r as pointers, in fact returns two variables. Then, the remainder is multiplied by 10, assigned to `a` & the function `divide` is called back, and again and again... – ssd Jul 08 '20 at 06:29
  • I got it!!! assuming 20/13=1|5|3|8|4|6 which is 20/13 + (7*10)/13 + (5*10)/13+(11*10)/13+(6*10)/13+(8*10)/13.... but what about r=a-*d*b ==> r=20-(20/13)*13 is not equal 0? haha help me understand this one. Thank you so much! – phatx88 Jul 08 '20 at 06:56
  • No! `20 - (20 / 13) * 13` is not equal to zero. As `d` is an `(int *)`, `*d = 20 / 13` is equal to `1` (an integer). Then, `20 - *d * 13` is (20 - 1 * 13) equal to 7. Maybe, you'll get a better understanding if you paste the code and inspect the values when debugging it. – ssd Jul 08 '20 at 07:01
  • Thanks, I take your advice to do more of dissecting small chunk of code to see how it works. it is clear to me now. – phatx88 Jul 08 '20 at 07:20