Home Database Mysql Tutorial 【编程之美】2.6精确表达浮点数

【编程之美】2.6精确表达浮点数

Jun 07, 2016 pm 03:18 PM
programming calculate question

【问题描述】: 在计算机中,使用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>
Copy after login
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1658
14
PHP Tutorial
1257
29
C# Tutorial
1231
24
Remove duplicate values ​​from PHP array using regular expressions Remove duplicate values ​​from PHP array using regular expressions Apr 26, 2024 pm 04:33 PM

How to remove duplicate values ​​from PHP array using regular expressions: Use regular expression /(.*)(.+)/i to match and replace duplicates. Iterate through the array elements and check for matches using preg_match. If it matches, skip the value; otherwise, add it to a new array with no duplicate values.

What is programming for and what is the use of learning it? What is programming for and what is the use of learning it? Apr 28, 2024 pm 01:34 PM

1. Programming can be used to develop various software and applications, including websites, mobile applications, games, and data analysis tools. Its application fields are very wide, covering almost all industries, including scientific research, health care, finance, education, entertainment, etc. 2. Learning programming can help us improve our problem-solving skills and logical thinking skills. During programming, we need to analyze and understand problems, find solutions, and translate them into code. This way of thinking can cultivate our analytical and abstract abilities and improve our ability to solve practical problems.

Unleash Your Inner Programmer: C for Absolute Beginners Unleash Your Inner Programmer: C for Absolute Beginners Oct 11, 2024 pm 03:50 PM

C is an ideal language for beginners to learn programming, and its advantages include efficiency, versatility, and portability. Learning C language requires: Installing a C compiler (such as MinGW or Cygwin) Understanding variables, data types, conditional statements and loop statements Writing the first program containing the main function and printf() function Practicing through practical cases (such as calculating averages) C language knowledge

Problem-Solving with Python: Unlock Powerful Solutions as a Beginner Coder Problem-Solving with Python: Unlock Powerful Solutions as a Beginner Coder Oct 11, 2024 pm 08:58 PM

Pythonempowersbeginnersinproblem-solving.Itsuser-friendlysyntax,extensivelibrary,andfeaturessuchasvariables,conditionalstatements,andloopsenableefficientcodedevelopment.Frommanagingdatatocontrollingprogramflowandperformingrepetitivetasks,Pythonprovid

Build browser-based applications with Golang Build browser-based applications with Golang Apr 08, 2024 am 09:24 AM

Build browser-based applications with Golang Golang combines with JavaScript to build dynamic front-end experiences. Install Golang: Visit https://golang.org/doc/install. Set up a Golang project: Create a file called main.go. Using GorillaWebToolkit: Add GorillaWebToolkit code to handle HTTP requests. Create HTML template: Create index.html in the templates subdirectory, which is the main template.

Get Go modules quickly and easily with Go Get Get Go modules quickly and easily with Go Get Apr 07, 2024 pm 09:48 PM

Through GoGet, you can quickly and easily obtain Go modules. The steps are as follows: Run in the terminal: goget[module-path], where module-path is the module path. GoGet automatically downloads the module and its dependencies. The location of the installation is specified by the GOPATH environment variable.

Collection of C++ programming puzzles: stimulate thinking and improve programming skills Collection of C++ programming puzzles: stimulate thinking and improve programming skills Jun 01, 2024 pm 10:26 PM

C++ programming puzzles cover algorithm and data structure concepts such as Fibonacci sequence, factorial, Hamming distance, maximum and minimum values ​​of arrays, etc. By solving these puzzles, you can consolidate C++ knowledge and improve algorithm understanding and programming skills.

The Key to Coding: Unlocking the Power of Python for Beginners The Key to Coding: Unlocking the Power of Python for Beginners Oct 11, 2024 pm 12:17 PM

Python is an ideal programming introduction language for beginners through its ease of learning and powerful features. Its basics include: Variables: used to store data (numbers, strings, lists, etc.). Data type: Defines the type of data in the variable (integer, floating point, etc.). Operators: used for mathematical operations and comparisons. Control flow: Control the flow of code execution (conditional statements, loops).

See all articles