搜尋
首頁資料庫mysql教程【编程之美】2.6精确表达浮点数

【问题描述】: 在计算机中,使用float或者double来存储小数是不能得到精确的。如果你希望得到精确计算结果,最好是用分数形式来表示小数。有限小数或者无限循环小数都可以转化为分数。比如: 0.9 = 9/10 0.333(3)= 1/3(括号中的数字表示是循环节) 当然


【问题描述】:

       在计算机中,使用float或者double来存储小数是不能得到精确值的。如果你希望得到精确计算结果,最好是用分数形式来表示小数。有限小数或者无限循环小数都可以转化为分数。比如:
0.9 = 9/10
0.333(3)= 1/3(括号中的数字表示是循环节)
当然一个小数可以用好几种分数形式来表示。如:
0.333(3)= 1/3 = 3/9
       给定一个有限小数或者无限循环小数,你能否以分母最小的分数形式来返回这个小数呢?如果输入为循环小数,循环节用括号标记出来。下面是一些可能的输入数据,如0.3、0.30、0.3(000)、0.3333(3333)、……


解法:

        拿到这样一个问题,我们往往会从最简单的情况入手,因为所有的小数都可以分解成一个整数和一个纯小数之和,不妨只考虑大于0,小于1的纯小数,且暂时不考虑分子和分母的约分,先设法将其表示为分数形式,然后再进行约分。题目中输入的小数,要么为有限小数X=0.a1a2an,要么为无限循环小数X=0.a1a2anb1b2bm),X表示式中的字母a1a2anb1b2bm都是0~9的数字,括号部分(b1b2bm)表示循环节,我们需要处理的就是以上两种情况。

        对于有限小数X=0.a1a2an来说,这个问题比较简单,X就等于(a1a2an/10n

       对于无限循环小数X=0.a1a2anb1b2bm)来说,其复杂部分在于小数点后同时有非循环部分和循环部分,我们可以做如下的转换:

X= 0.a1a2anb1b2bm

10nX= a1a2an.b1b2bm

10nX= a1a2an+0.b1b2bm

X =a1a2an+0.b1b2bm))/10n

        对于整数部分a1a2an,不需要做额外处理,只需要把小数部分转化为分数形式再加上这个整数即可。对于后面的无限循环部分,可以采用如下方式进行处理:

Y=0. b1b2bm,那么

10m *Y=b1b2bm.b1b2bm

10m *Y=b1b2bm+0.b1b2bm

10m *Y-Y=b1b2bm

Y= b1b2bm/10m-1

Y代入前面的X的等式可得:

X=a1a2an+Y/10n

=a1a2an+ b1b2bm/10m-1))/10n

=((a1a2an*10m-1+b1b2bm))/((10m-1*10n

         至此,便可以得到任意一个有限小数或无限循环小数的分数表示,但是此时分母未必是最简的,接下来的任务就是让分母最小,即对分子和分母进行约分,这个相对比较简单。对于任意一个分数A/B,可以简化为(A/GcdA,B))/B/GcdA,B)),其中Gcd函数为求AB的最大公约数,这就涉及本书中的算法(2.7节“最大公约数问题”),其中有很巧妙的解法,请读者阅读具体的章节,这里就不再赘述。

         综上所述,先求得小数的分数表示方式,再对其分子分母进行约分,便能够得到分母最小的分数表现形式。

例如,对于小数0.333),根据上述方法,可以转化为分数:

0.333

=3 *102-1+ 33/((102-1*10

=3*99+33/990

= 1 / 3

对于小数0. 285714285714),我们也可以算出:

0. 285714285714

285714 *106-1+ 285714((106-1*106

285714*999999 +285714/ 999999000000

= 285714 / 999999

= 2/7


以下给出代码,简单实现:

void Cal(char* str)
{
	char *p=str;
	char *q=str,*q1=str;//q和q1分别存储(和)的指针
	while(*p!='\0')
	{
		if(*p=='(')
		{
			q=p;
		}
		if(*p==')')
		{
			q1=p;
		}
		p++;
	}
	if(q==q1)
	{
		cout<br>
<br>
<p><span>为了更完善,分两种情况:</span></p>
<p><span>1、对于小数的情况,不用定义数组形式:</span></p>
<p></p><pre class="brush:php;toolbar:false">#include <iostream>

using namespace std;

long long gcd(long long a, long long b)
{
	if (a >1,b>>1)
				a >>= 1;
				b >>= 1;
				k++;
			}
			else
				// a为偶数,b为奇数,f(a,b)=f(a>>1,b)
				a >>= 1;
		}
		else
		{
			if ((b&1) == 0)
				// a为奇数,b为偶数,f(a,b)=f(a,b>>1)
				b >>= 1;
			else
				// a,b均是奇数,f(a,b)=f(a-b,b)
				a = a-b;
		}
		if (a <br>
<br>

<p><span>2、<span>用于大整数,定义了大整数类型,以及对应的加减乘除、比较移位运算</span></span></p>
<p></p>
<pre class="brush:php;toolbar:false">#include <iostream>
#include <cstring>
#include <string>
using namespace std;

// 大整数类型
#define MAXLEN 1000
struct HP {int len, s[MAXLEN];};

void PrintHP(HP x) 
{
	for (int i=x.len; i>=1; i--)
		cout  1 && !c.s[c.len]) c.len--;
}

// 大整数的比较
int HPCompare(const HP &x, const HP &y)
{
	if (x.len > y.len) return 1;
	if (x.len 1 && (x.s[i]==y.s[i])) i--;
	return x.s[i] - y.s[i];
}

// 大整数的乘法
void Multi(const HP a, const HP b, HP &c)
{
	int i, j;
	// 对乘法结果赋初值,以方便之后的+=运算
	c.len = a.len + b.len;
	for (i=1; i1 && !c.s[i]) i--;
	c.len = i;
}

// 大整数的除法
void Divide(const HP a, const HP b, HP &c, HP &d)
{
	int i, j;
	// 用余数d存被除数a的前i位数据,用来多次减去除数b,以得到商c
	d.len = 1; d.s[1] = 0;
	for (i=a.len; i>0; i--)
	{
		if (!(d.len == 1 && d.s[1] == 0))
		{
			// i没移一位,余数d也移位
			for (j=d.len; j>0; j--)
				d.s[j+1] = d.s[j];
			d.len++;
		}
		d.s[1] = a.s[i];
		c.s[i] = 0;
		// 余数d大于除数b时,才可以进行减操作
		while ((j=HPCompare(d,b)) >= 0)
		{
			Subtract(d, b, d);
			c.s[i]++;
			if (j == 0) break;
		}
	}
	c.len = a.len;
	while (c.len > 1 && c.s[c.len] == 0)
		c.len--;
}
// 十进位右移
void RightShift(HP &x, int k)
{
	for (int i=1; i=1; i--)
		x.s[i+k] = x.s[i];
	for (i=k; i>=1; i--)
		x.s[i] = 0;
	x.len += k;
}
// 求大整数的最大公约数
void GCD(HP a, HP b, HP &c)
{
	if (b.len == 1 && b.s[1] == 0)
	{
		c.len = a.len;
		memcpy(c.s, a.s, (a.len+1)*sizeof(int));
	}
	else
	{
		HP m, n;
		Divide(a, b, m, n);
		GCD(b, n, c);
	}
}

int main()
{
	string str;
	string strc, stra, strb;
	cin >> str;
	int posc = str.find('.');
	int posa = str.find('(');
	int posb = str.find(')');
	strc = str.substr(0, posc);
	if (posc = 0)
		{
			strb = str.substr(posa+1, posb-posa-1);
			// 循环部分
			Str2HP(strb.c_str(), b);
			HP m = tmp;
			LeftShift(m, strb.size());
			Subtract(m, tmp, m);
			// 乘以10^(|b|-1)
			Multi(up, m, up);
			Plus(up, b, up);
			Multi(down, m, down);
		}
		// 求分子分母的最大公约数
		GCD(down, up, tmp);
		HP h;
		Divide(down, tmp, down, h);
		Divide(up, tmp, up, h);
		PrintHP(up); cout <br>
<br>

<p><br>
</p>


</string></cstring></iostream>
陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
计算机编程中常见的if语句是什么计算机编程中常见的if语句是什么Jan 29, 2023 pm 04:31 PM

计算机编程中常见的if语句是条件判断语句。if语句是一种选择分支结构,它是依据明确的条件选择选择执行路径,而不是严格按照顺序执行,在编程实际运用中要根据程序流程选择适合的分支语句,它是依照条件的结果改变执行的程序;if语句的简单语法“if(条件表达式){// 要执行的代码;}”。

Python编程:详解命名元组(namedtuple)的使用要点Python编程:详解命名元组(namedtuple)的使用要点Apr 11, 2023 pm 09:22 PM

前言本文继续来介绍Python集合模块,这次主要简明扼要的介绍其内的命名元组,即namedtuple的使用。闲话少叙,我们开始——记得点赞、关注和转发哦~ ^_^创建命名元组Python集合中的命名元组类namedTuples为元组中的每个位置赋予意义,并增强代码的可读性和描述性。它们可以在任何使用常规元组的地方使用,且增加了通过名称而不是位置索引方式访问字段的能力。其来自Python内置模块collections。其使用的常规语法方式为:import collections XxNamedT

如何在Go中进行图像处理?如何在Go中进行图像处理?May 11, 2023 pm 04:45 PM

作为一门高效的编程语言,Go在图像处理领域也有着不错的表现。虽然Go本身的标准库中没有提供专门的图像处理相关的API,但是有一些优秀的第三方库可以供我们使用,比如GoCV、ImageMagick和GraphicsMagick等。本文将重点介绍使用GoCV进行图像处理的方法。GoCV是一个高度依赖于OpenCV的Go语言绑定库,其

PHP8.0中的邮件库PHP8.0中的邮件库May 14, 2023 am 08:49 AM

最近,PHP8.0发布了一个新的邮件库,使得在PHP中发送和接收电子邮件变得更加容易。这个库具有强大的功能,包括构建电子邮件,发送电子邮件,解析电子邮件,获取附件和解决电子邮件获得卡住的问题。在很多项目中,我们都需要使用电子邮件来进行通信和一些必备的业务操作。而PHP8.0中的邮件库可以让我们轻松地实现这一点。接下来,我们将探索这个新的邮件库,并了解如何在我

PHP8.0中的DOMDocumentPHP8.0中的DOMDocumentMay 14, 2023 am 08:18 AM

随着PHP8.0的发布,DOMDocument作为PHP内置的XML解析库,也有了新的变化和增强。DOMDocument在PHP中的重要性不言而喻,尤其在处理XML文档方面,它的功能十分强大,而且使用起来也十分简单。本文将介绍PHP8.0中DOMDocument的新特性和应用。一、DOMDocument概述DOM(DocumentObjectModel)

学Python,还不知道main函数吗学Python,还不知道main函数吗Apr 12, 2023 pm 02:58 PM

Python 中的 main 函数充当程序的执行点,在 Python 编程中定义 main 函数是启动程序执行的必要条件,不过它仅在程序直接运行时才执行,而在作为模块导入时不会执行。要了解有关 Python main 函数的更多信息,我们将从如下几点逐步学习:什么是 Python 函数Python 中 main 函数的功能是什么一个基本的 Python main() 是怎样的Python 执行模式Let’s get started什么是 Python 函数相信很多小伙伴对函数都不陌生了,函数是可

PHP8.0中的Symbol类型PHP8.0中的Symbol类型May 14, 2023 am 08:39 AM

PHP8.0是PHP语言的最新版本,自发布以来已经引发了广泛的关注和争议。其中,最引人瞩目的新特性之一就是Symbol类型。Symbol类型是PHP8.0中新增的一种数据类型,它类似于JavaScript中的Symbol类型,可用于表示独一无二的值。这意味着,两个Symbol类型的值即使完全相同,它们也是不相等的。Symbol类型的使用可以避免在不同的代码段

为拯救童年回忆,开发者决定采用古法编程:用Flash高清重制了一款游戏为拯救童年回忆,开发者决定采用古法编程:用Flash高清重制了一款游戏Apr 11, 2023 pm 10:16 PM

两年多前,Adobe 发布了一则引人关注的公告 —— 将在 2020 年 12 月 31 日终止支持 Flash,宣告了一个时代的结束。一晃两年过去了,Adobe 早已从官方网站中删除了 Flash Player 早期版本的所有存档,并阻止基于 Flash 的内容运行。微软也已经终止对 Adobe Flash Player 的支持,并禁止其在任何 Microsoft 浏览器上运行。Adobe Flash Player 组件于 2021 年 7 月通过 Windows 更新永久删除。当 Flash

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版