【问题标题】:Write a program to take 2 numbers to divide it, take sum of the decimals from division value to output编写一个程序,取2个数除,取除法值的小数之和输出
【发布时间】:2020-07-08 02:21:18
【问题描述】:

该程序将采用 3 个整数值 a、b 和 N。 该程序将从 (a/b) 的除法值到 N 个数字中找到小数之和。 例如:

抱歉,我的技术英语不是很好,我的程序(C 语言)应该执行以下操作:

  1. 它采用 a、b 和 N 的值
  2. 它执行a和b的划分
  3. 将浮点数除法分为整数和小数部分
  4. 它添加到向下舍入的小数部分的总和
  5. 它通过乘以 10 来更新基本除法值
  6. 更新n=N循环的条件
  7. printf 中的输出。

但是,我的程序只给出正确的值,直到 a=252525 b=99 N=33 output=171 我认为这是错误的。请帮我纠正我的算法。

#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);
    
}

【问题讨论】:

  • 为什么用long double modf() 调用double 函数? modfl() 将提供 long double 分数。否则为什么不简单地做一个double 划分?
  • 对于较大的 N 值,您使用的技术将不起作用。例如,在测试 5 中,正确的除法结果是 336.666666... 6s 永远重复。但是div 中的结果实际上是 336.6666666666666666574148...所以您的代码最多只能用于 16 的 N。
  • 修复程序没有简单的方法。我认为您需要使用小学长除法算法来实现除法,并寻找重复模式。或者只是继续除法,直到你计算出足够的数字。
  • 要么必须实现长除法算法,要么必须使用任意精度算术库来解决任意整数的问题。
  • 是的,我根本不知道或尝试那么多功能。很高兴知道我可以简单地使用 modfl() 而不是 modf。

标签: c double decimal floor


【解决方案1】:

如果您设计自己的“整数除法函数”,它会更简单(并且准确,正如@user3386109 指出的那样,浮点运算将随着小数位数的增加而开始降低精度);类似下面的东西(函数divide)。

编辑: 测试a = 252525, b = 99, N = 33;输出是 199,这对我来说似乎没问题。小数部分类似于“.7575757575...”;前 32 位加起来是 16 * 12 = 192,加上最后一个“7”(第 33 位)等于 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;
}

【讨论】:

  • 我不太了解两个整数相除背后的数学原理。我希望有人可以更喜欢我,而不是一个解释得更好的链接。据我了解 unsigned int a=20, b=13, 所以 20/13 = 1?它是如何工作的?
  • 该函数将 20 除以 13,得到除法 1 和余数 7。该函数具有参数 d 和 r 作为指针,实际上返回两个变量。然后,将余数乘以 10,分配给 a 并回调函数 divide,一次又一次……
  • 我明白了!!!假设 20/13=1|5|3|8|4|6 即 20/13 + (7*10)/13 + (5*10)/13+(11*10)/13+(6*10 )/13+(8*10)/13.... 但是 r=a-db ==> r=20-(20/13)*13 不等于 0 呢?哈哈帮我理解这个。非常感谢!
  • 不! 20 - (20 / 13) * 13 不等于零。由于d(int *)*d = 20 / 13 等于1(整数)。那么20 - *d * 13 就是 (20 - 1 * 13) 等于 7。也许,如果你粘贴代码并在调试时检查值,你会更好地理解。
  • 谢谢,我听从您的建议,更多地剖析一小段代码,看看它是如何工作的。我现在很清楚了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多