`$ 1 - \frac{1}{2} + \frac{1}{3} -\frac{1}{4} + \cdots + \frac{1}{99} - \frac{1}{100} $`的C语言程序的

$ 1 - \frac{1}{2} + \frac{1}{3} -\frac{1}{4} + \cdots + \frac{1}{99} - \frac{1}{100} $的C语言程序的解法及其相关的问题

一、C语言 定义浮点数类型解法(double类型)

#include<stdio.h>
#include<stdio.h>

int main(){
	double result = 1.0;			//定义result存储程序执行的结果
	int iter = 2;					
	while(iter <= 100){
		if(iter % 2 == 0){
			result = result - 1/(double)iter;  //当iter为偶数时,result 减 1 / iter
		}else{
			result = result + 1/(double)iter;	//当iter为奇数时,result 加 1 / iter
		}
		iter++;
	}
	printf("1 - 1/2 + 1/3 - 1/4 + ... + 1/99 -1/100 = %f\n",result);
	return 0;
}

计算结果 0.688172

二、C语言 定义分数结构体解法

#include <stdio.h>

typedef struct{			//定义分数结构体
	long int numerator;	//分子
	long int denominator;	//分母
}Fraction;

long int gcd(long int a,long int b){   //辗转相除法求最大公因数
	while(b != 0){
	long int temp = b;
	 b = a % b;
	 a = temp;
	}
	return a;
}

Fraction simplify(Fraction f){				//分数化简
	long int common_divisor = gcd(f.numerator,f.denominator);
	f.numerator /= common_divisor;
	f.denominator /= common_divisor;

	if(f.denominator < 0){
		f.denominator = -f.denominator;
		f.numerator = -f.numerator;
	}
	return f;
}

Fraction add(Fraction f1,Fraction f2){			//加法
	Fraction result;
	result.numerator = f1.numerator * f2.denominator + f2.numerator * f1.denominator;
	result.denominator = f1.denominator * f2.denominator;
	return simplify(result);
}

Fraction subtract(Fraction f1,Fraction f2){		//减法
	Fraction result;
        result.numerator = f1.numerator * f2.denominator - f2.numerator * f1.denominator;
        result.denominator = f1.denominator * f2.denominator;
        return simplify(result);

}

Fraction multiply(Fraction f1,Fraction f2){			//乘法
	Fraction result;
	result.numerator = f1.numerator * f2.numerator;
	result.denominator = f1.denominator * f2.denominator;
	return simplify(result);
}

Fraction divide(Fraction f1,Fraction f2){				//除法
	Fraction result;
	result.numerator = f1.numerator * f2.denominator;
	result.denominator = f1.denominator * f2.numerator;
	return result;
}

void printFraction(Fraction f){				//打印分数
	if(f.denominator == 1){
		printf("%ld\n",f.numerator);
	}else{
		printf("%ld/%ld\n",f.numerator,f.denominator);
	}
}


int main(){
	Fraction f1 = {2,3};
	Fraction f2 = {3,4};

	Fraction sum = add(f1,f2);
	Fraction difference = subtract(f1,f2);
	Fraction product = multiply(f1,f2);
	Fraction quotient = divide(f1,f2);
	printf("Sum = ");
	printFraction(sum);
	printf("Difference = ");
        printFraction(difference);
       	printf("Product = ");
	printFraction(product);
 	printf("Quotient = ");
	printFraction(quotient);

//测试一下分数结构体的定义和相关函数是否正确

	Fraction xsum = {1,1};
	long int iter = 2;
	while(iter <= 100){
		Fraction x = {1,iter};
		if(iter % 2 == 0){
			xsum = subtract(xsum,x);
		}else{
			xsum = add(xsum,x);
		}
		iter = iter + 1;
	}
	printf("Xsum = ");    //int类型定义的Fraction,计算这个问题数字上溢出
	printFraction(xsum);
			
	return 0;
}
  1. int 类型定义的Fraction计算机结果是$ \frac{70732297}{385373376}$,对应的小数0.18354225124259752,显然int类型定义Fraction计算过程中整数出现了上溢
  2. 该换用long int类型定义Fraction计算结果是$\frac{1165334734037754711}{2019692938525864768}$ 对应的小数值是0.5769860912066713long int类型定义Fraction精度仍然不足,整数计算出现了上溢
  3. 改用long long int类型,计算的结果为$ \frac{1165334734037754711}{2019692938525864768}$ ,和用long int类型定义的结果相同;
  4. 上述用intlong intlong long int定义的结果都没用达到或者接近第一种方法用浮点数计算的结果
  5. 电脑操作系统是64位Windows11系统,int类型占32位,long intlong long int类型都占64位(long long int类型的规定可能大于long int类型所占的字节数多。但实际上,由于系统的限制long long int类型和long int类型占用的字节数一要多)

三、Python自带的分数库计算

from fractions import Fraction

xsum = Fraction(1, 1)
for i in range(2, 101):
    x = Fraction(1, i)
    if i % 2 == 0:
        xsum = xsum - x
    else:
        xsum = xsum + x

print(xsum)
print(float(xsum))
  1. 打印的结果是$sum = \frac{47979622564155786918478609039662898122617}{69720375229712477164533808935312303556800}$,对应的小数值0.6881721793101953

  2. 方法三和方法一结算的结果近似,而且能够提供结果的分数形式。但对于分数结果分子分母的大小已经远远超过64位整数的表示范围。对于C语言定义分数结构体的方式进行计算,需要超过64位的整数类型。

  3. Python的分数库所能计算的精度要大于C语言默认类型定义Fraction结构体所能计算的精度

总结

  1. 用C语言编写代码要注意不同数据类型所能代表的数字大小,防止产生整数溢出和浮点数的上溢和下溢,适当情况下要考虑使用数组表示长整数和使用外部库;
  2. 需要高精度计算,可以考虑Python的高精度数学库,相比使用C语言,Python的库使用起来更方便
  3. 使用C语言编写代码时,要注意不同的数据类型表示数字的大小,有时候,long intlong long intdoublelong double表示的数字范围相同。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值