埃及分数 c语言,埃及分数(二)

斐波那契法(即贪心算法)

在“埃及分数(一)”中,我们讨论了斐波那契法(即贪心算法)。现在使用 C 语言写一个程序来实现该算法吧,下面就是 EgyptianFibonacci.c:

1: #include

2: #include

3:

4: int main(int argc, char *argv[])

5: {

6: if (argc != 3) return 1;

7: mpz_t z, w;

8: mpq_t x, y;

9: mpz_inits(z, w, 0);

10: mpq_inits(x, y, 0);

11: mpz_set_str(z, argv[1], 10);

12: mpz_set_str(w, argv[2], 10);

13: mpq_set_num(x, z);

14: mpq_set_den(x, w);

15: mpq_canonicalize(x);

16: gmp_printf("%Qd:", x);

17: if (mpq_sgn(x) > 0)

18: {

19: while (1)

20: {

21: mpz_cdiv_q(z, mpq_denref(x), mpq_numref(x));

22: gmp_printf(" %Zd", z);

23: if (mpz_cmp_si(mpq_numref(x), 1) == 0) break;

24: mpq_set_z(y, z);

25: mpq_inv(y, y);

26: mpq_sub(x, x, y);

27: }

28: }

29: mpq_clears(x, y, 0);

30: mpz_clears(z, w, 0);

31: printf("\n");

32: return 0;

33: }

这个程序使用了 GUN MP 高精度算术库,编译时要加上 -lgmp 参数:

$ clang -o EgyptianFibonacci EgyptianFibonacci.c -lgmp

试运行一下:

$ ./EgyptianFibonacci 5 121

5/121: 25 757 763309 873960180913 1527612795642093418846225

$ ./EgyptianFibonacci 118 121

118/121: 2 3 8 60 4840

嗯,运行结果符合我们的预期。

计算单位分数的和

再写个 C 语言程序来验算结果吧,下面就是 UnitFractionSum.c:

1: #include

2:

3: int main(int argc, char *argv[])

4: {

5: mpz_t n;

6: mpz_init(n);

7: mpq_t sum, q;

8: mpq_inits(sum, q, 0);

9: for (int i = 1; i < argc; i++)

10: {

11: mpz_set_str(n, argv[i], 10);

12: mpq_set_si(q, 1, 1);

13: mpq_set_den(q, n);

14: mpq_canonicalize(q);

15: mpq_add(sum, sum, q);

16: }

17: gmp_printf("%Qd\n", sum);

18: mpz_clear(n);

19: mpq_clears(sum, q, 0);

20: return 0;

21: }

编译:

$ clang -o UnitFractionSum UnitFractionSum.c -lgmp

运行:

$ ./UnitFractionSum 25 757 763309 873960180913 1527612795642093418846225

5/121

$ ./UnitFractionSum 2 3 8 60 4840

118/121

一切正常。

GNU MP 高精度算术库简介

本文中的两个 C 语言程序使用了 GNU MP 高精度算术库。这个库用起来非常简单:

mpz_t 表示整数类型。

mpq_t 表示有理数(分数)类型。

mpz_ 开头的函数用于处理整数。

mpq_ 开头的函数用于处理有理数。

这些类型使用前必须用 mp?_init 函数初始化。

使用后必须用 mp?_clear 函数释放。

mp?_set 开头的函数用于设定初值。

mpq_canonicalize 函数用于对有理数进行规范化,即对分数进行约分。

mp?_add 等函数进行算术运算。

详情请参阅参考资料[2]。

参考资料

421c5c3285046bf30a303410e987933b.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值