C++类fractionizer实现浮点数到分数的转换

需积分: 16 1 下载量 190 浏览量 更新于2024-12-30 收藏 56KB ZIP 举报
资源摘要信息:"fractionizer类库的介绍与使用方法" 在编程领域,特别是在处理数学问题和数值计算时,常常需要将浮点数(浮点值)转换为分数形式。这是因为分数形式可以提供精确值,而浮点数由于表示方式的限制,往往只能提供近似值。特别是在金融计算、科学计算等领域,对数值的精确性要求非常高,因此需要一种方法将浮点数转换为分数形式。 fractionizer是一个C++类库,它利用连续分数的概念,将浮点值准确地转换为分数表示。连续分数是一种数学概念,通过一个整数序列来表示一个实数,可以将其表示为最简分数形式。 ### 使用方法: 1. 首先需要包含相关的头文件,这在描述中提到的是`fractionizer.h`和`print_float.h`。头文件是C++源代码文件的一部分,其中包含了类的声明和函数的声明。 2. 接下来,声明需要的变量,比如在描述中提到了`num`(分子)和`denom`(分母)两个变量,分别用于存储转换后的分数的分子和分母。 3. 调用fractionizer类中的fractionize静态成员函数。这个函数的原型没有在描述中给出,但可以假设它接收一个浮点数(比如val)作为输入参数,并通过引用参数的方式返回分数的分子和分母。 4. 使用`std::cout`来输出转换后的分数。`std::cout`是C++中的标准输出流,可以用来向控制台打印信息。在描述中,使用了一个嵌入的`Print_float::print`函数来将分数的分子和分母打印出来,这暗示了`Print_float`类具有一个能够将数值转换为字符串的成员函数`print`。 5. 描述中提到的也可以使用更高精度的浮点数类型,比如`long double`,以获得更高精度的分数表示。 ### 相关知识点: - **浮点数**:是一种数学表示,能够表示非常大或者非常小的数值。在计算机中,浮点数通常由符号位、指数位和尾数位组成,可以提供一定的精度,但是仍然会有舍入误差。 - **分数**:是一种表示形式,可以精确地表示一些有理数,即可以写成两个整数比例形式的数。在数学中,分数的表示是最精确的。 - **连续分数**:数学上,连续分数是一种表示实数的方法,它由整数序列构成,并以一个无限连分数的形式存在。这种表示方法特别适合于无理数的近似计算。 - **C++类和成员函数**:在C++中,类是一种数据类型,可以包含数据成员和成员函数。成员函数可以是静态的,静态成员函数不依赖于类的对象实例,可以直接通过类来调用。 - **头文件包含**:在C++中,使用`#include`预处理指令来包含头文件,这些头文件中通常包含了类的声明、函数的声明和宏定义等。 - **标准输出流std::cout**:是C++标准库中的输出流对象,用于向标准输出(通常是控制台)写入数据。 - **数据类型精度**:在C++中,基本的浮点数据类型有float、double和long double,它们表示的数值范围和精度是不同的,其中long double提供了最高精度。 通过以上知识点,我们可以看出fractionizer类库是为了解决在C++程序中将浮点数准确转换为分数表示的需求,提供了一种可靠且精确的数值计算手段。这在需要处理高精度数学计算的场景中是非常有用的。
478 浏览量
11076 浮点数的分数表达 时间限制:1000MS 内存限制:1000K 提交次数:0 通过次数:0 题型: 编程题 语言: 无限制 Description 在计算机中,用float或double来存储小数有时不能得到精确值,若要精确表达一个浮点数的计算结果, 最好用分数来表示小数,有限小数或无限循环小数都可以转化为分数,无限循环小数的循环节用括号标记出来。如: 0.9 = 9/10 0.(3) = 0.3(3) = 0.3(33) = 1/3 当然一个小数可以用好几种分数形式来表示,我们只感兴趣最简的分数形式(即分母最小),如: 0.3(33) = 1/3 = 3/9 因为任何一个数都可以转化为一个整数和一个纯小数之和,整数部分较为简单无需做额外处理,只要将纯小数部分转化为分数形式,整数部分的分数部分就很简单了。 现在给定一个正的纯小数(这个纯小数为有限小数或无限循环小数),请你以最简分数形式来返回这个纯小数。 输入格式 给定一个纯小数,若是无限循环小数,用括号标记循环节,输入小数表达不超过100个字符。 输出格式 输出:化为最简分数形式,分子在前,分母在后,中间空格连接。 输入样例 0.3(33) 输出样例 1 3 提示 此题涉及如下几个问题: 一、字符串输入的问题 此题采用字符串接收输入,大家在接受数据的时候,不要用(c=getchar())!='\n'诸如此类一个字符一个字符接受, 然后判断是否是回车符号来结束输入,这样的方式在你本机运行不会有问题,但OJ系统中会有错误,无法输出结果, 因为OJ的测试平台行末并非'\n'字符。这里接受数据用scanf的%s,或cin等,会自动判别结束字符的,你就不要在你程序里专门去判别或吸收回车字符。 char a[105]; scanf("%s",a); 或cin >> a; 二、高精度或64位整数表示的问题 此题题目规定:输入小数表达不超过100个字符。 如此长的数,本意要大家用高精度数的运算来求解. 但后台测试数据没有做如此之长,放松一些吧,用64位整数也是允许通过的! 实现上,所有分子分母的变量,以及求最大公约数,都须用64位整数。 编译环境不同,对64位整数的定义和输入输出略有不同: 1)gnu gcc/g++ 中long long类型,或unsigned long long, 输入输出用cin和cout直接输出,用scanf和printf也可以的。 long long a; cin >> a; cout << a; 也可以使用:(注意一下,本OJ系统的gcc/g++不支持64位整数以"%I64d"形式输出, 但标准gnu gcc是支持如下的,在codeblocks上可以无误运行) scanf("%I64d",&a); printf("%I64d",a); 2)vc中用__int64类型,或unsigned __int64 scanf("%I64d",&a); printf("%I64d",a); vc下,64整数不要用cin和cout来输入输出,据说vc下64位整数兼容不好,会出错!大家可测试一下如下程序在vc下是否会出错? __int64 a; cin >> a; cout << a; 三、本题的解题思路 考虑输入的是纯小数,先暂时不考虑分子和分母有公因子的情况。 (1) 假设有限小数:X = 0.a1a2…an,式中的a1,a2,…,an都是0~9的数字。 X = 0.a1a2…an = a1a2…an/10^n (2) 假设无限循环小数:X = 0.a1a2…an(b1b2…bm),式中的a1,a2,…,an, b1,b2,…,bm都是0~9的数字,括号为循环节。 第一步,先将X化为只有循环部分的纯小数。 X = 0.a1a2…an(b1b2…bm) (10^n)*X = a1a2…an + 0.(b1b2…bm) X = (a1a2…an + 0.(b1b2…bm)) / (10^n) 上式中,a1a2…an是整数部分,容易解决。重点考虑小数部分0.(b1b2…bm)如何化为分数形式,再加上整数部分即可。 第二步,考虑Y = 0.(b1b2…bm),将Y化为分数, (10^m)*Y = b1b2…bm + 0.(b1b2…bm) ((10^m)-1)*Y = b1b2…bm Y = b1b2…bm / ((10^m)-1) 将第二步的Y带入第一步的X,可得: X = (a1a2…an+Y)/(10^n) = ((a1a2…an)*((10^m)-1) + (b1b2…bm)) / ((10^m)-1)*(10^n) 此时,可以将任何一个有限小数或无限循环小数,化为分数表示,分数的分子和分母如上分析的公式。 但此时的分子分母未必是最简化的,对分子分母再进行约分, 删去公共的因子,A/B = (A/GCD(A,B))/(B/GCD(A,B)),化为简单形式。 作者 zhengchan --------------------------------------------------------------------------------