第八周项目二(2)顺序串算法测试-串的反序排列

问题及代码

这里这里只给出main.cpp代码

算法库见算法库

main.cpp

/*
*Copyright(c)2017,烟台大学计算机学院
*All right reserved.
*文件名:main.cpp sqstring.h string.cpp
*作者:王万兴
*完成日期:2017年10月19日
*版本号:v1.0
*
*问题描述:串的反序排列
*输入描述:无
*程序输出:见运行结果
*/
#include <stdio.h>
#include "sqString.h"
void Invert(SqString &s)
{
    int i;
    char temp;
    for (i=0; i<s.length/2; i++)
    {
        temp = s.data[i];
        s.data[i]=s.data[s.length-i-1];
        s.data[s.length-i-1] = temp;
    }
}

int main()
{
    SqString s;
    printf("正序排列:");
    StrAssign(s, "abcdefg");
    DispStr(s);
    Invert(s);
    printf("反序排列:");
    DispStr(s);
    return 0;
}

运行结果


知识点总结
倒序排列,与平常的倒序没有区别。
任务描述 请编写一个Python程序,实现十进制整数到进制整数的转换; 请编写一个Python程序,实现十进制小数到进制小数的转换。请注意,length参数用于指定转换后进制位数; 请编写一个Python程序,实现进制整数分别到八进制和十六进制整数的转换。请注意,由参数oh来指定是转成八进制(’o’)还是十六进制(’h’)。 相关知识 一个数值能够用不同进制表示,这些表示之间存在转换关系。计算机使用进制表示数值,而人类惯用十进制。当将数值输入到计算机中时,必须将十进制转换为进制,而将计算机中的数值输出时,一般要将其转换为十进制,以便于人阅读和理解。对整数而言,虽然进制不同,但是一个数的不同进制表示在数值上是相等的,因此有: (N) 10 ​ =a n ​ ×2 n +⋯+a 1 ​ ×2 1 +a 0 ​ ×2 0 (1) 上式等号左边下标10表示用十进制表示整数N。由上式可得,将进制整数转换为十进制整数,可直接按照等号右边的式子,做十进制的乘法和加法就能完成。例如,进制整数(10111) 2 ​ 可按照上式转换为十进制整数: 1×2 4 +0×2 3 +1×2 2 +1×2 1 +1×2 0 =(23) 10 ​ 而十进制整数到进制整数的转换可采用“除2取余”法,其方法也可由上式推导出来。N代表给定的十进制整数,a n ​ 、…a 1 ​ 、a 0 ​ 分别代表需要求出的各位进制数字。(1)式等号两边同时除以2,等式保持不变。从等式右边可看出,N除以2得到的余数是a 0 ​ ,得到的商为a n ​ ×2 n−1 +⋯+a 2 ​ ×2 1 +a 1 ​ ,对商再除以2,又得余数a 1 ​ 和商a n ​ ×2 n−2 +⋯+a 3 ​ ×2 1 +a 2 ​ ,等等,依此进行下去,直到商为0。这个过程中得到的所有余数或为0 或为1,将它们按照求得的顺序的反序拼接在一起,就得到所需要的进制表示形式。 如下图1给出了将(37) 10 ​ 转换成进制的过程,所得结果为: (37) 10 ​ =(100101) 2 ​ 。 进制小数与十进制小数之间的转换方法也能通过公式推导出来。如下式所示,其中0.a-1a-2… a-m是进制小数,下标m可能为无穷大,N是等价的十进制小数,下标m可能为无穷大,N是等价的十进制小数。 (N) 10 ​ =a −1 ​ ×2 −1 +a −2 ​ ×22 ++⋯+a −m ​ ×2 −m (2) 同样地,将进制小数转换为十进制小数,可直接按照等号右边的式子,做十进制的除法和加法即可。例如,已知(0.1011) 2 ​ ,求其等价的十进制小数,转换过程为: 1×2 −1 +0×22 +1×23 +1×2 −4 =(0.6875) 10 ​ 十进制小数到进制小数的转换可采用“乘2取整”法,将公式(2)两边同时乘以2,等式仍成立,此时,右边整数部分变成a −1 ​ ,小数部分变为: a −2 ​ ×2 −1 +a −3 ​ ×22 +⋯+a −m ​ ×2 −m+1 再对结果的小数部分两边乘以2,右边整数部分变成a −2 ​ ,小数部分为: a −3 ​ ×2 −1 +⋯+a −m ​ ×2 −m+2 依此进行下去,直到乘2的结果中小数部分为0,或者达到所需要的进制位数。对于很多十进制小数,上述乘2的过程,达不到结果小数部分为0的情形。因此,十进制小数到进制小数的转换是不精确的转换。下图2中给出了十进制小数到进制小数转换的两个例子,左边是将十进制数0.625转换成进制数,它是精确转换;右边是将十进制数0.34转换成进制数,它是不精确转换。从图中可得: 从图2的例子还可知道,用进制来表示十进制数时,有些数不能精确表示,只能在表示能力范围内给出近似表示。这与可用的进制位数和十进制数自身相关: 可用的进制位数是由计算机的能力决定的,对32位计算机,可以用来表示数的位数通常有8、16和32位,位数越多,能表示的数值越多,精度也越高; 对不能精确转化为进制的十进制小数,即便能用的进制位数很多,也无法精确地表示出来。例如,0.1这个十进制小数转换成进制小数是一个无限循环小数,理论上就无法精确表示。 除了表示数值,还需表示数值的符号: 如“+”或“-”。通常用进制表示的最高位来表示数值的符号位,0表示正数、1表示负数。因此,如果能用的进制位为8位,那么,(23) 10 ​ =(00010111) 2 ​ 。 而(23) 10 ​ =(10010111) 2 ​ ,这种表示方式称为原码表示。 计算机中通常用浮点数来表示实数,浮点数是指有理数中某特定子集的数的数字表示,在计算机中用以近似表示任意的某个实数。浮点计算是指浮点数参与的运算,这种运算通常伴随着因为无法精确表示而进行的近似或舍入。考察下面的Python语句: >>>print(0.1) 0.1 >>>print("%.17lf" % 0.1) 0.10000000000000001 0.1这个十进制小数转换成进制数时,是一个无限循环小数,在计算机中通常用浮点数表示,是一种近似的表示。而现代程序设计语言的输出带有一定的智能,在保证误差较小的前提下会自动舍入。所以第一个print语句打印0.1。但是,当用第2个print语句指定输出精度时,就能看到0.1在计算机中不是真正的0.1,而是有一定的误差的。同理,浮点数之间用>、<、==来比较大小是不可取的,需要看两个浮点数是否在合理的误差范围,如果误差合理,即认为相等;否则,两个在十进制中相等的数可能在计算机中是不相等的。 此外,浮点数的误差会在其计算过程中累积,考察下面的Python程序: x = 0.0 for i in range(100): x += 0.1 print("%.17lf" % x) print(x) 运行该程序得到的输出如下所示:第1行是x的较为精确的表示,而第2行是print自动舍入,显示出来的看似正确的结果。 9.99999999999998046 10.0 八进制和十六进制是计算机领域使用的辅助计数法,用于计算机与人类的交互。八进制或十六进制与进制之间的转换很直观和简单,在认知上接近进制。这些原因促进人们引入八进制和十六进制。由于这两种进制是辅助计数方法,人们不关心对八进制数或十六进制数的运算,在此对八进制运算和十六进制的运算不进行讨论。 八进制的基本组成为: 基本数字符号有八个,分别是0、1、23、4、5、6、7; 基本符号形成字符的语法规则与进制相同; 解释合法字符的语义规则是“逢八进一”; 基本运算(不予讨论)。 2374、101、0.564、3.21和11.101等都是合法的八进制数表示,而9021、11.2.5和76+2等都不是合法的八进制数字。注意八进制(101) 8 ​ 代表的数值与进制(101) 2 ​ 代表的数值不相等,同样(11.101) 8 ​ 与(11.101) 2 ​ 不等价。 十六进制的基本组成是: 表示数的基本符号有十六个,0∽9的数字符号和A∽F的字母符号。字母A∽F分别代表数10∽15; 基本符号形成字符的语法规则与进制相同; 解释合法字符的语义规则是“逢十六进一”; 基本运算(不予讨论)。 57A8、1101、1370、901B、FFFF、E.D1C和0.ABC等都是合法的十六进制数字,而A12H、BE.12.3、A+1F等都不是合法的十六进制数(1101) 16 ​ 和(1101) 2 ​ 代表不同数值。 进制数与八进制数以及进制数与十六进制数之间有一种直接的对应关系。一位八进制能表示0∽7之间的8个数值,恰好对应3进制能表示的数值范围;一位十六进制表示0∽15之间的16个数值,恰好对应4位进制能表示的数值范围。用这种对应关系可推导出它们之间的转换方法,其中进制到八进制(或十六进制)的转换方法称为“三位压缩成一位”(或“四位压缩成一位”),八进制(或十六进制)到进制之间的转换方法称为“一位展开成三位”(或“一位展开成四位”)。 此处详细介绍进制与八进制之间的转换方法。对于进制与十六进制之间的转换,其方法与进制与八进制之间的转换类似,只要将其中的“三”字换成“四”即可。 进制到八进制的转换分两个步骤进行,第一步转换数值的整数部分,第步转换数值的小数部分。 对于整数部分,按照三位一组,从右至左逐步将进制数字字符分组。如果最左边的一组进制不够三位,最高位填充0,直到该组包含三位进制数字。对于每组的三位进制数字表示的数,用对应的八进制数字字符替换之,就得到了整数部分的八进制表示; 对于小数部分,按照三位一组,从左至右逐步将进制数字字符分组。如果最右边一组的进制数字不够三位,最低位填充0,直到该组包含三位进制数字。同样,对于每组的三位进制数字表示的数,用等价的八进制数字字符替换之,就得到了小数部分的八进制表示。将这两部的结果合并起来,小数点的位保持不变,就产生了与该进制数等价的八进制表示。 下面的连等式显示了将进制数(1010010101.10111) 2 ​ 转换为等价八进制数的过程: (1010010101.10111) 2 ​ =(1010010101.10111) 2 ​ =(001010010101.101110) 2 ​ =(1225.56) 8 ​ 类似地,可得到该进制数的十六进制表示: (1010010101.10111) 2 ​ =(1010010101.10111) 2 ​ =(001010010101.10111000) 2 ​ =(295.B8) 16 ​ 从八进制到进制的转换很简单,只需将八进制数的每个字符代表的数值用对应的三位进制字符替代,并且小数点位不变。转换后高位0和低位0可以省略。例如,将八进制数(3745) 8 ​ 转换为对应的进制数的过程如下: (3705.426) 8 ​ =(011111000101.100010110) 2 ​ =(11111000101.10001011) 2 ​ 用类似方法,能将十六进制数(1F59.A28) 16 ​ 转换成对应的进制表示: (1F59.A28) 16 ​ =(0001111101011001.101000101000) 2 ​ =(1111101011001.101000101) 2 ​ 编程要求 本关的编程任务是补全12-1.py文件中的dec2bin_Int、dec2bin_Point以及bin2oh函数,以实现“任务描述”中的三个题目。 具体请参见后续测试样例。 本关涉及的代码文件12-1.py的代码框架如下: from random import * #第一题 def dec2bin_Int(dec): binum = &#39;&#39; # 请在此添加代码,补全函数dec2bin_Int #-----------Begin---------- #------------End----------- return binum[::-1] #第题 def dec2bin_Point(dec, length): binum = &#39;&#39; # 请在此添加代码,补全函数dec2bin_Point #-----------Begin---------- #------------End----------- return &#39;0.&#39;+binum #第三题 def bin2oh(binum, oh): result = &#39;&#39; if oh == &#39;o&#39;: # 请在此添加代码,补全函数bin2oh #-----------Begin---------- #------------End----------- return result elif oh == &#39;h&#39;: # 请在此添加代码,补全函数bin2oh #-----------Begin---------- #------------End----------- return result if __name__ == &#39;__main__&#39;: seed(0) tests = [randint(1, n) for n in [10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000]] bins = [] for num in tests: binum = dec2bin_Int(num) print(binum) bins.append(binum) print(&#39;*&#39;*30) seed(99) decimals = [] for i in range(10): decimals.append(round(random(),3)) print(decimals) for dec in decimals: print(dec2bin_Point(dec, 8)) print(&#39;*&#39; * 30) print(tests) for binum in bins: print(bin2oh(binum, &#39;o&#39;)) print(&#39;*&#39; * 30) for binum in bins: print(bin2oh(binum, &#39;h&#39;)) 测试说明 下面是对平台如何评测你所实现功能的说明及样例测试。本关的测试文件是12-1.py自身。 以下是平台对12-1.py的样例测试集: 测试输入:无输入 预期输出: 111 1110 11 100010 10000011 11111001 110011111 11101011001 100110110101 1111010000001 ****************************** [0.404, 0.2, 0.179, 0.248, 0.76, 0.251, 0.383, 0.684, 0.539, 0.938] 0.01100111 0.00110011 0.00101101 0.00111111 0.11000010 0.01000000 0.01100010 0.10101111 0.10001001 0.11110000 ****************************** [7, 14, 3, 34, 131, 249, 415, 1881, 2485, 7809] 7 16 3 42 203 371 637 3531 4665 17201 ****************************** 7 E 3 22 83 F9 19F 759 9B5 1E81任务描述 请编写一个Python程序,实现十进制整数到进制整数的转换; 请编写一个Python程序,实现十进制小数到进制小数的转换。请注意,length参数用于指定转换后进制位数; 请编写一个Python程序,实现进制整数分别到八进制和十六进制整数的转换。请注意,由参数oh来指定是转成八进制(’o’)还是十六进制(’h’)。 相关知识 一个数值能够用不同进制表示,这些表示之间存在转换关系。计算机使用进制表示数值,而人类惯用十进制。当将数值输入到计算机中时,必须将十进制转换为进制,而将计算机中的数值输出时,一般要将其转换为十进制,以便于人阅读和理解。对整数而言,虽然进制不同,但是一个数的不同进制表示在数值上是相等的,因此有: (N) 10 ​ =a n ​ ×2 n +⋯+a 1 ​ ×2 1 +a 0 ​ ×2 0 (1) 上式等号左边下标10表示用十进制表示整数N。由上式可得,将进制整数转换为十进制整数,可直接按照等号右边的式子,做十进制的乘法和加法就能完成。例如,进制整数(10111) 2 ​ 可按照上式转换为十进制整数: 1×2 4 +0×2 3 +1×2 2 +1×2 1 +1×2 0 =(23) 10 ​ 而十进制整数到进制整数的转换可采用“除2取余”法,其方法也可由上式推导出来。N代表给定的十进制整数,a n ​ 、…a 1 ​ 、a 0 ​ 分别代表需要求出的各位进制数字。(1)式等号两边同时除以2,等式保持不变。从等式右边可看出,N除以2得到的余数是a 0 ​ ,得到的商为a n ​ ×2 n−1 +⋯+a 2 ​ ×2 1 +a 1 ​ ,对商再除以2,又得余数a 1 ​ 和商a n ​ ×2 n−2 +⋯+a 3 ​ ×2 1 +a 2 ​ ,等等,依此进行下去,直到商为0。这个过程中得到的所有余数或为0 或为1,将它们按照求得的顺序的反序拼接在一起,就得到所需要的进制表示形式。 如下图1给出了将(37) 10 ​ 转换成进制的过程,所得结果为: (37) 10 ​ =(100101) 2 ​ 。 进制小数与十进制小数之间的转换方法也能通过公式推导出来。如下式所示,其中0.a-1a-2… a-m是进制小数,下标m可能为无穷大,N是等价的十进制小数,下标m可能为无穷大,N是等价的十进制小数。 (N) 10 ​ =a −1 ​ ×2 −1 +a −2 ​ ×22 ++⋯+a −m ​ ×2 −m (2) 同样地,将进制小数转换为十进制小数,可直接按照等号右边的式子,做十进制的除法和加法即可。例如,已知(0.1011) 2 ​ ,求其等价的十进制小数,转换过程为: 1×2 −1 +0×22 +1×23 +1×2 −4 =(0.6875) 10 ​ 十进制小数到进制小数的转换可采用“乘2取整”法,将公式(2)两边同时乘以2,等式仍成立,此时,右边整数部分变成a −1 ​ ,小数部分变为: a −2 ​ ×2 −1 +a −3 ​ ×22 +⋯+a −m ​ ×2 −m+1 再对结果的小数部分两边乘以2,右边整数部分变成a −2 ​ ,小数部分为: a −3 ​ ×2 −1 +⋯+a −m ​ ×2 −m+2 依此进行下去,直到乘2的结果中小数部分为0,或者达到所需要的进制位数。对于很多十进制小数,上述乘2的过程,达不到结果小数部分为0的情形。因此,十进制小数到进制小数的转换是不精确的转换。下图2中给出了十进制小数到进制小数转换的两个例子,左边是将十进制数0.625转换成进制数,它是精确转换;右边是将十进制数0.34转换成进制数,它是不精确转换。从图中可得: 从图2的例子还可知道,用进制来表示十进制数时,有些数不能精确表示,只能在表示能力范围内给出近似表示。这与可用的进制位数和十进制数自身相关: 可用的进制位数是由计算机的能力决定的,对32位计算机,可以用来表示数的位数通常有8、16和32位,位数越多,能表示的数值越多,精度也越高; 对不能精确转化为进制的十进制小数,即便能用的进制位数很多,也无法精确地表示出来。例如,0.1这个十进制小数转换成进制小数是一个无限循环小数,理论上就无法精确表示。 除了表示数值,还需表示数值的符号: 如“+”或“-”。通常用进制表示的最高位来表示数值的符号位,0表示正数、1表示负数。因此,如果能用的进制位为8位,那么,(23) 10 ​ =(00010111) 2 ​ 。 而(23) 10 ​ =(10010111) 2 ​ ,这种表示方式称为原码表示。 计算机中通常用浮点数来表示实数,浮点数是指有理数中某特定子集的数的数字表示,在计算机中用以近似表示任意的某个实数。浮点计算是指浮点数参与的运算,这种运算通常伴随着因为无法精确表示而进行的近似或舍入。考察下面的Python语句: >>>print(0.1) 0.1 >>>print("%.17lf" % 0.1) 0.10000000000000001 0.1这个十进制小数转换成进制数时,是一个无限循环小数,在计算机中通常用浮点数表示,是一种近似的表示。而现代程序设计语言的输出带有一定的智能,在保证误差较小的前提下会自动舍入。所以第一个print语句打印0.1。但是,当用第2个print语句指定输出精度时,就能看到0.1在计算机中不是真正的0.1,而是有一定的误差的。同理,浮点数之间用>、<、==来比较大小是不可取的,需要看两个浮点数是否在合理的误差范围,如果误差合理,即认为相等;否则,两个在十进制中相等的数可能在计算机中是不相等的。 此外,浮点数的误差会在其计算过程中累积,考察下面的Python程序: x = 0.0 for i in range(100): x += 0.1 print("%.17lf" % x) print(x) 运行该程序得到的输出如下所示:第1行是x的较为精确的表示,而第2行是print自动舍入,显示出来的看似正确的结果。 9.99999999999998046 10.0 八进制和十六进制是计算机领域使用的辅助计数法,用于计算机与人类的交互。八进制或十六进制与进制之间的转换很直观和简单,在认知上接近进制。这些原因促进人们引入八进制和十六进制。由于这两种进制是辅助计数方法,人们不关心对八进制数或十六进制数的运算,在此对八进制运算和十六进制的运算不进行讨论。 八进制的基本组成为: 基本数字符号有八个,分别是0、1、23、4、5、6、7; 基本符号形成字符的语法规则与进制相同; 解释合法字符的语义规则是“逢八进一”; 基本运算(不予讨论)。 2374、101、0.564、3.21和11.101等都是合法的八进制数表示,而9021、11.2.5和76+2等都不是合法的八进制数字。注意八进制(101) 8 ​ 代表的数值与进制(101) 2 ​ 代表的数值不相等,同样(11.101) 8 ​ 与(11.101) 2 ​ 不等价。 十六进制的基本组成是: 表示数的基本符号有十六个,0∽9的数字符号和A∽F的字母符号。字母A∽F分别代表数10∽15; 基本符号形成字符的语法规则与进制相同; 解释合法字符的语义规则是“逢十六进一”; 基本运算(不予讨论)。 57A8、1101、1370、901B、FFFF、E.D1C和0.ABC等都是合法的十六进制数字,而A12H、BE.12.3、A+1F等都不是合法的十六进制数(1101) 16 ​ 和(1101) 2 ​ 代表不同数值。 进制数与八进制数以及进制数与十六进制数之间有一种直接的对应关系。一位八进制能表示0∽7之间的8个数值,恰好对应3进制能表示的数值范围;一位十六进制表示0∽15之间的16个数值,恰好对应4位进制能表示的数值范围。用这种对应关系可推导出它们之间的转换方法,其中进制到八进制(或十六进制)的转换方法称为“三位压缩成一位”(或“四位压缩成一位”),八进制(或十六进制)到进制之间的转换方法称为“一位展开成三位”(或“一位展开成四位”)。 此处详细介绍进制与八进制之间的转换方法。对于进制与十六进制之间的转换,其方法与进制与八进制之间的转换类似,只要将其中的“三”字换成“四”即可。 进制到八进制的转换分两个步骤进行,第一步转换数值的整数部分,第步转换数值的小数部分。 对于整数部分,按照三位一组,从右至左逐步将进制数字字符分组。如果最左边的一组进制不够三位,最高位填充0,直到该组包含三位进制数字。对于每组的三位进制数字表示的数,用对应的八进制数字字符替换之,就得到了整数部分的八进制表示; 对于小数部分,按照三位一组,从左至右逐步将进制数字字符分组。如果最右边一组的进制数字不够三位,最低位填充0,直到该组包含三位进制数字。同样,对于每组的三位进制数字表示的数,用等价的八进制数字字符替换之,就得到了小数部分的八进制表示。将这两部的结果合并起来,小数点的位保持不变,就产生了与该进制数等价的八进制表示。 下面的连等式显示了将进制数(1010010101.10111) 2 ​ 转换为等价八进制数的过程: (1010010101.10111) 2 ​ =(1010010101.10111) 2 ​ =(001010010101.101110) 2 ​ =(1225.56) 8 ​ 类似地,可得到该进制数的十六进制表示: (1010010101.10111) 2 ​ =(1010010101.10111) 2 ​ =(001010010101.10111000) 2 ​ =(295.B8) 16 ​ 从八进制到进制的转换很简单,只需将八进制数的每个字符代表的数值用对应的三位进制字符替代,并且小数点位不变。转换后高位0和低位0可以省略。例如,将八进制数(3745) 8 ​ 转换为对应的进制数的过程如下: (3705.426) 8 ​ =(011111000101.100010110) 2 ​ =(11111000101.10001011) 2 ​ 用类似方法,能将十六进制数(1F59.A28) 16 ​ 转换成对应的进制表示: (1F59.A28) 16 ​ =(0001111101011001.101000101000) 2 ​ =(1111101011001.101000101) 2 ​ 编程要求 本关的编程任务是补全12-1.py文件中的dec2bin_Int、dec2bin_Point以及bin2oh函数,以实现“任务描述”中的三个题目。 具体请参见后续测试样例。 本关涉及的代码文件12-1.py的代码框架如下: from random import * #第一题 def dec2bin_Int(dec): binum = &#39;&#39; # 请在此添加代码,补全函数dec2bin_Int #-----------Begin---------- #------------End----------- return binum[::-1] #第题 def dec2bin_Point(dec, length): binum = &#39;&#39; # 请在此添加代码,补全函数dec2bin_Point #-----------Begin---------- #------------End----------- return &#39;0.&#39;+binum #第三题 def bin2oh(binum, oh): result = &#39;&#39; if oh == &#39;o&#39;: # 请在此添加代码,补全函数bin2oh #-----------Begin---------- #------------End----------- return result elif oh == &#39;h&#39;: # 请在此添加代码,补全函数bin2oh #-----------Begin---------- #------------End----------- return result if __name__ == &#39;__main__&#39;: seed(0) tests = [randint(1, n) for n in [10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000]] bins = [] for num in tests: binum = dec2bin_Int(num) print(binum) bins.append(binum) print(&#39;*&#39;*30) seed(99) decimals = [] for i in range(10): decimals.append(round(random(),3)) print(decimals) for dec in decimals: print(dec2bin_Point(dec, 8)) print(&#39;*&#39; * 30) print(tests) for binum in bins: print(bin2oh(binum, &#39;o&#39;)) print(&#39;*&#39; * 30) for binum in bins: print(bin2oh(binum, &#39;h&#39;)) 测试说明 下面是对平台如何评测你所实现功能的说明及样例测试。本关的测试文件是12-1.py自身。 以下是平台对12-1.py的样例测试集: 测试输入:无输入 预期输出: 111 1110 11 100010 10000011 11111001 110011111 11101011001 100110110101 1111010000001 ****************************** [0.404, 0.2, 0.179, 0.248, 0.76, 0.251, 0.383, 0.684, 0.539, 0.938] 0.01100111 0.00110011 0.00101101 0.00111111 0.11000010 0.01000000 0.01100010 0.10101111 0.10001001 0.11110000 ****************************** [7, 14, 3, 34, 131, 249, 415, 1881, 2485, 7809] 7 16 3 42 203 371 637 3531 4665 17201 ****************************** 7 E 3 22 83 F9 19F 759 9B5 1E81任务描述 请编写一个Python程序,实现十进制整数到进制整数的转换; 请编写一个Python程序,实现十进制小数到进制小数的转换。请注意,length参数用于指定转换后进制位数; 请编写一个Python程序,实现进制整数分别到八进制和十六进制整数的转换。请注意,由参数oh来指定是转成八进制(’o’)还是十六进制(’h’)。 相关知识 一个数值能够用不同进制表示,这些表示之间存在转换关系。计算机使用进制表示数值,而人类惯用十进制。当将数值输入到计算机中时,必须将十进制转换为进制,而将计算机中的数值输出时,一般要将其转换为十进制,以便于人阅读和理解。对整数而言,虽然进制不同,但是一个数的不同进制表示在数值上是相等的,因此有: (N) 10 ​ =a n ​ ×2 n +⋯+a 1 ​ ×2 1 +a 0 ​ ×2 0 (1) 上式等号左边下标10表示用十进制表示整数N。由上式可得,将进制整数转换为十进制整数,可直接按照等号右边的式子,做十进制的乘法和加法就能完成。例如,进制整数(10111) 2 ​ 可按照上式转换为十进制整数: 1×2 4 +0×2 3 +1×2 2 +1×2 1 +1×2 0 =(23) 10 ​ 而十进制整数到进制整数的转换可采用“除2取余”法,其方法也可由上式推导出来。N代表给定的十进制整数,a n ​ 、…a 1 ​ 、a 0 ​ 分别代表需要求出的各位进制数字。(1)式等号两边同时除以2,等式保持不变。从等式右边可看出,N除以2得到的余数是a 0 ​ ,得到的商为a n ​ ×2 n−1 +⋯+a 2 ​ ×2 1 +a 1 ​ ,对商再除以2,又得余数a 1 ​ 和商a n ​ ×2 n−2 +⋯+a 3 ​ ×2 1 +a 2 ​ ,等等,依此进行下去,直到商为0。这个过程中得到的所有余数或为0 或为1,将它们按照求得的顺序的反序拼接在一起,就得到所需要的进制表示形式。 如下图1给出了将(37) 10 ​ 转换成进制的过程,所得结果为: (37) 10 ​ =(100101) 2 ​ 。 进制小数与十进制小数之间的转换方法也能通过公式推导出来。如下式所示,其中0.a-1a-2… a-m是进制小数,下标m可能为无穷大,N是等价的十进制小数,下标m可能为无穷大,N是等价的十进制小数。 (N) 10 ​ =a −1 ​ ×2 −1 +a −2 ​ ×22 ++⋯+a −m ​ ×2 −m (2) 同样地,将进制小数转换为十进制小数,可直接按照等号右边的式子,做十进制的除法和加法即可。例如,已知(0.1011) 2 ​ ,求其等价的十进制小数,转换过程为: 1×2 −1 +0×22 +1×23 +1×2 −4 =(0.6875) 10 ​ 十进制小数到进制小数的转换可采用“乘2取整”法,将公式(2)两边同时乘以2,等式仍成立,此时,右边整数部分变成a −1 ​ ,小数部分变为: a −2 ​ ×2 −1 +a −3 ​ ×22 +⋯+a −m ​ ×2 −m+1 再对结果的小数部分两边乘以2,右边整数部分变成a −2 ​ ,小数部分为: a −3 ​ ×2 −1 +⋯+a −m ​ ×2 −m+2 依此进行下去,直到乘2的结果中小数部分为0,或者达到所需要的进制位数。对于很多十进制小数,上述乘2的过程,达不到结果小数部分为0的情形。因此,十进制小数到进制小数的转换是不精确的转换。下图2中给出了十进制小数到进制小数转换的两个例子,左边是将十进制数0.625转换成进制数,它是精确转换;右边是将十进制数0.34转换成进制数,它是不精确转换。从图中可得: 从图2的例子还可知道,用进制来表示十进制数时,有些数不能精确表示,只能在表示能力范围内给出近似表示。这与可用的进制位数和十进制数自身相关: 可用的进制位数是由计算机的能力决定的,对32位计算机,可以用来表示数的位数通常有8、16和32位,位数越多,能表示的数值越多,精度也越高; 对不能精确转化为进制的十进制小数,即便能用的进制位数很多,也无法精确地表示出来。例如,0.1这个十进制小数转换成进制小数是一个无限循环小数,理论上就无法精确表示。 除了表示数值,还需表示数值的符号: 如“+”或“-”。通常用进制表示的最高位来表示数值的符号位,0表示正数、1表示负数。因此,如果能用的进制位为8位,那么,(23) 10 ​ =(00010111) 2 ​ 。 而(23) 10 ​ =(10010111) 2 ​ ,这种表示方式称为原码表示。 计算机中通常用浮点数来表示实数,浮点数是指有理数中某特定子集的数的数字表示,在计算机中用以近似表示任意的某个实数。浮点计算是指浮点数参与的运算,这种运算通常伴随着因为无法精确表示而进行的近似或舍入。考察下面的Python语句: >>>print(0.1) 0.1 >>>print("%.17lf" % 0.1) 0.10000000000000001 0.1这个十进制小数转换成进制数时,是一个无限循环小数,在计算机中通常用浮点数表示,是一种近似的表示。而现代程序设计语言的输出带有一定的智能,在保证误差较小的前提下会自动舍入。所以第一个print语句打印0.1。但是,当用第2个print语句指定输出精度时,就能看到0.1在计算机中不是真正的0.1,而是有一定的误差的。同理,浮点数之间用>、<、==来比较大小是不可取的,需要看两个浮点数是否在合理的误差范围,如果误差合理,即认为相等;否则,两个在十进制中相等的数可能在计算机中是不相等的。 此外,浮点数的误差会在其计算过程中累积,考察下面的Python程序: x = 0.0 for i in range(100): x += 0.1 print("%.17lf" % x) print(x) 运行该程序得到的输出如下所示:第1行是x的较为精确的表示,而第2行是print自动舍入,显示出来的看似正确的结果。 9.99999999999998046 10.0 八进制和十六进制是计算机领域使用的辅助计数法,用于计算机与人类的交互。八进制或十六进制与进制之间的转换很直观和简单,在认知上接近进制。这些原因促进人们引入八进制和十六进制。由于这两种进制是辅助计数方法,人们不关心对八进制数或十六进制数的运算,在此对八进制运算和十六进制的运算不进行讨论。 八进制的基本组成为: 基本数字符号有八个,分别是0、1、23、4、5、6、7; 基本符号形成字符的语法规则与进制相同; 解释合法字符的语义规则是“逢八进一”; 基本运算(不予讨论)。 2374、101、0.564、3.21和11.101等都是合法的八进制数表示,而9021、11.2.5和76+2等都不是合法的八进制数字。注意八进制(101) 8 ​ 代表的数值与进制(101) 2 ​ 代表的数值不相等,同样(11.101) 8 ​ 与(11.101) 2 ​ 不等价。 十六进制的基本组成是: 表示数的基本符号有十六个,0∽9的数字符号和A∽F的字母符号。字母A∽F分别代表数10∽15; 基本符号形成字符的语法规则与进制相同; 解释合法字符的语义规则是“逢十六进一”; 基本运算(不予讨论)。 57A8、1101、1370、901B、FFFF、E.D1C和0.ABC等都是合法的十六进制数字,而A12H、BE.12.3、A+1F等都不是合法的十六进制数(1101) 16 ​ 和(1101) 2 ​ 代表不同数值。 进制数与八进制数以及进制数与十六进制数之间有一种直接的对应关系。一位八进制能表示0∽7之间的8个数值,恰好对应3进制能表示的数值范围;一位十六进制表示0∽15之间的16个数值,恰好对应4位进制能表示的数值范围。用这种对应关系可推导出它们之间的转换方法,其中进制到八进制(或十六进制)的转换方法称为“三位压缩成一位”(或“四位压缩成一位”),八进制(或十六进制)到进制之间的转换方法称为“一位展开成三位”(或“一位展开成四位”)。 此处详细介绍进制与八进制之间的转换方法。对于进制与十六进制之间的转换,其方法与进制与八进制之间的转换类似,只要将其中的“三”字换成“四”即可。 进制到八进制的转换分两个步骤进行,第一步转换数值的整数部分,第步转换数值的小数部分。 对于整数部分,按照三位一组,从右至左逐步将进制数字字符分组。如果最左边的一组进制不够三位,最高位填充0,直到该组包含三位进制数字。对于每组的三位进制数字表示的数,用对应的八进制数字字符替换之,就得到了整数部分的八进制表示; 对于小数部分,按照三位一组,从左至右逐步将进制数字字符分组。如果最右边一组的进制数字不够三位,最低位填充0,直到该组包含三位进制数字。同样,对于每组的三位进制数字表示的数,用等价的八进制数字字符替换之,就得到了小数部分的八进制表示。将这两部的结果合并起来,小数点的位保持不变,就产生了与该进制数等价的八进制表示。 下面的连等式显示了将进制数(1010010101.10111) 2 ​ 转换为等价八进制数的过程: (1010010101.10111) 2 ​ =(1010010101.10111) 2 ​ =(001010010101.101110) 2 ​ =(1225.56) 8 ​ 类似地,可得到该进制数的十六进制表示: (1010010101.10111) 2 ​ =(1010010101.10111) 2 ​ =(001010010101.10111000) 2 ​ =(295.B8) 16 ​ 从八进制到进制的转换很简单,只需将八进制数的每个字符代表的数值用对应的三位进制字符替代,并且小数点位不变。转换后高位0和低位0可以省略。例如,将八进制数(3745) 8 ​ 转换为对应的进制数的过程如下: (3705.426) 8 ​ =(011111000101.100010110) 2 ​ =(11111000101.10001011) 2 ​ 用类似方法,能将十六进制数(1F59.A28) 16 ​ 转换成对应的进制表示: (1F59.A28) 16 ​ =(0001111101011001.101000101000) 2 ​ =(1111101011001.101000101) 2 ​ 编程要求 本关的编程任务是补全12-1.py文件中的dec2bin_Int、dec2bin_Point以及bin2oh函数,以实现“任务描述”中的三个题目。 具体请参见后续测试样例。 本关涉及的代码文件12-1.py的代码框架如下: from random import * #第一题 def dec2bin_Int(dec): binum = &#39;&#39; # 请在此添加代码,补全函数dec2bin_Int #-----------Begin---------- #------------End----------- return binum[::-1] #第题 def dec2bin_Point(dec, length): binum = &#39;&#39; # 请在此添加代码,补全函数dec2bin_Point #-----------Begin---------- #------------End----------- return &#39;0.&#39;+binum #第三题 def bin2oh(binum, oh): result = &#39;&#39; if oh == &#39;o&#39;: # 请在此添加代码,补全函数bin2oh #-----------Begin---------- #------------End----------- return result elif oh == &#39;h&#39;: # 请在此添加代码,补全函数bin2oh #-----------Begin---------- #------------End----------- return result if __name__ == &#39;__main__&#39;: seed(0) tests = [randint(1, n) for n in [10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000]] bins = [] for num in tests: binum = dec2bin_Int(num) print(binum) bins.append(binum) print(&#39;*&#39;*30) seed(99) decimals = [] for i in range(10): decimals.append(round(random(),3)) print(decimals) for dec in decimals: print(dec2bin_Point(dec, 8)) print(&#39;*&#39; * 30) print(tests) for binum in bins: print(bin2oh(binum, &#39;o&#39;)) print(&#39;*&#39; * 30) for binum in bins: print(bin2oh(binum, &#39;h&#39;)) 测试说明 下面是对平台如何评测你所实现功能的说明及样例测试。本关的测试文件是12-1.py自身。 以下是平台对12-1.py的样例测试集: 测试输入:无输入 预期输出: 111 1110 11 100010 10000011 11111001 110011111 11101011001 100110110101 1111010000001 ****************************** [0.404, 0.2, 0.179, 0.248, 0.76, 0.251, 0.383, 0.684, 0.539, 0.938] 0.01100111 0.00110011 0.00101101 0.00111111 0.11000010 0.01000000 0.01100010 0.10101111 0.10001001 0.11110000 ****************************** [7, 14, 3, 34, 131, 249, 415, 1881, 2485, 7809] 7 16 3 42 203 371 637 3531 4665 17201 ****************************** 7 E 3 22 83 F9 19F 759 9B5 1E81任务描述 请编写一个Python程序,实现十进制整数到进制整数的转换; 请编写一个Python程序,实现十进制小数到进制小数的转换。请注意,length参数用于指定转换后进制位数; 请编写一个Python程序,实现进制整数分别到八进制和十六进制整数的转换。请注意,由参数oh来指定是转成八进制(’o’)还是十六进制(’h’)。 相关知识 一个数值能够用不同进制表示,这些表示之间存在转换关系。计算机使用进制表示数值,而人类惯用十进制。当将数值输入到计算机中时,必须将十进制转换为进制,而将计算机中的数值输出时,一般要将其转换为十进制,以便于人阅读和理解。对整数而言,虽然进制不同,但是一个数的不同进制表示在数值上是相等的,因此有: (N) 10 ​ =a n ​ ×2 n +⋯+a 1 ​ ×2 1 +a 0 ​ ×2 0 (1) 上式等号左边下标10表示用十进制表示整数N。由上式可得,将进制整数转换为十进制整数,可直接按照等号右边的式子,做十进制的乘法和加法就能完成。例如,进制整数(10111) 2 ​ 可按照上式转换为十进制整数: 1×2 4 +0×2 3 +1×2 2 +1×2 1 +1×2 0 =(23) 10 ​ 而十进制整数到进制整数的转换可采用“除2取余”法,其方法也可由上式推导出来。N代表给定的十进制整数,a n ​ 、…a 1 ​ 、a 0 ​ 分别代表需要求出的各位进制数字。(1)式等号两边同时除以2,等式保持不变。从等式右边可看出,N除以2得到的余数是a 0 ​ ,得到的商为a n ​ ×2 n−1 +⋯+a 2 ​ ×2 1 +a 1 ​ ,对商再除以2,又得余数a 1 ​ 和商a n ​ ×2 n−2 +⋯+a 3 ​ ×2 1 +a 2 ​ ,等等,依此进行下去,直到商为0。这个过程中得到的所有余数或为0 或为1,将它们按照求得的顺序的反序拼接在一起,就得到所需要的进制表示形式。 如下图1给出了将(37) 10 ​ 转换成进制的过程,所得结果为: (37) 10 ​ =(100101) 2 ​ 。 进制小数与十进制小数之间的转换方法也能通过公式推导出来。如下式所示,其中0.a-1a-2… a-m是进制小数,下标m可能为无穷大,N是等价的十进制小数,下标m可能为无穷大,N是等价的十进制小数。 (N) 10 ​ =a −1 ​ ×2 −1 +a −2 ​ ×22 ++⋯+a −m ​ ×2 −m (2) 同样地,将进制小数转换为十进制小数,可直接按照等号右边的式子,做十进制的除法和加法即可。例如,已知(0.1011) 2 ​ ,求其等价的十进制小数,转换过程为: 1×2 −1 +0×22 +1×23 +1×2 −4 =(0.6875) 10 ​ 十进制小数到进制小数的转换可采用“乘2取整”法,将公式(2)两边同时乘以2,等式仍成立,此时,右边整数部分变成a −1 ​ ,小数部分变为: a −2 ​ ×2 −1 +a −3 ​ ×22 +⋯+a −m ​ ×2 −m+1 再对结果的小数部分两边乘以2,右边整数部分变成a −2 ​ ,小数部分为: a −3 ​ ×2 −1 +⋯+a −m ​ ×2 −m+2 依此进行下去,直到乘2的结果中小数部分为0,或者达到所需要的进制位数。对于很多十进制小数,上述乘2的过程,达不到结果小数部分为0的情形。因此,十进制小数到进制小数的转换是不精确的转换。下图2中给出了十进制小数到进制小数转换的两个例子,左边是将十进制数0.625转换成进制数,它是精确转换;右边是将十进制数0.34转换成进制数,它是不精确转换。从图中可得: 从图2的例子还可知道,用进制来表示十进制数时,有些数不能精确表示,只能在表示能力范围内给出近似表示。这与可用的进制位数和十进制数自身相关: 可用的进制位数是由计算机的能力决定的,对32位计算机,可以用来表示数的位数通常有8、16和32位,位数越多,能表示的数值越多,精度也越高; 对不能精确转化为进制的十进制小数,即便能用的进制位数很多,也无法精确地表示出来。例如,0.1这个十进制小数转换成进制小数是一个无限循环小数,理论上就无法精确表示。 除了表示数值,还需表示数值的符号: 如“+”或“-”。通常用进制表示的最高位来表示数值的符号位,0表示正数、1表示负数。因此,如果能用的进制位为8位,那么,(23) 10 ​ =(00010111) 2 ​ 。 而(23) 10 ​ =(10010111) 2 ​ ,这种表示方式称为原码表示。 计算机中通常用浮点数来表示实数,浮点数是指有理数中某特定子集的数的数字表示,在计算机中用以近似表示任意的某个实数。浮点计算是指浮点数参与的运算,这种运算通常伴随着因为无法精确表示而进行的近似或舍入。考察下面的Python语句: >>>print(0.1) 0.1 >>>print("%.17lf" % 0.1) 0.10000000000000001 0.1这个十进制小数转换成进制数时,是一个无限循环小数,在计算机中通常用浮点数表示,是一种近似的表示。而现代程序设计语言的输出带有一定的智能,在保证误差较小的前提下会自动舍入。所以第一个print语句打印0.1。但是,当用第2个print语句指定输出精度时,就能看到0.1在计算机中不是真正的0.1,而是有一定的误差的。同理,浮点数之间用>、<、==来比较大小是不可取的,需要看两个浮点数是否在合理的误差范围,如果误差合理,即认为相等;否则,两个在十进制中相等的数可能在计算机中是不相等的。 此外,浮点数的误差会在其计算过程中累积,考察下面的Python程序: x = 0.0 for i in range(100): x += 0.1 print("%.17lf" % x) print(x) 运行该程序得到的输出如下所示:第1行是x的较为精确的表示,而第2行是print自动舍入,显示出来的看似正确的结果。 9.99999999999998046 10.0 八进制和十六进制是计算机领域使用的辅助计数法,用于计算机与人类的交互。八进制或十六进制与进制之间的转换很直观和简单,在认知上接近进制。这些原因促进人们引入八进制和十六进制。由于这两种进制是辅助计数方法,人们不关心对八进制数或十六进制数的运算,在此对八进制运算和十六进制的运算不进行讨论。 八进制的基本组成为: 基本数字符号有八个,分别是0、1、23、4、5、6、7; 基本符号形成字符的语法规则与进制相同; 解释合法字符的语义规则是“逢八进一”; 基本运算(不予讨论)。 2374、101、0.564、3.21和11.101等都是合法的八进制数表示,而9021、11.2.5和76+2等都不是合法的八进制数字。注意八进制(101) 8 ​ 代表的数值与进制(101) 2 ​ 代表的数值不相等,同样(11.101) 8 ​ 与(11.101) 2 ​ 不等价。 十六进制的基本组成是: 表示数的基本符号有十六个,0∽9的数字符号和A∽F的字母符号。字母A∽F分别代表数10∽15; 基本符号形成字符的语法规则与进制相同; 解释合法字符的语义规则是“逢十六进一”; 基本运算(不予讨论)。 57A8、1101、1370、901B、FFFF、E.D1C和0.ABC等都是合法的十六进制数字,而A12H、BE.12.3、A+1F等都不是合法的十六进制数(1101) 16 ​ 和(1101) 2 ​ 代表不同数值。 进制数与八进制数以及进制数与十六进制数之间有一种直接的对应关系。一位八进制能表示0∽7之间的8个数值,恰好对应3进制能表示的数值范围;一位十六进制表示0∽15之间的16个数值,恰好对应4位进制能表示的数值范围。用这种对应关系可推导出它们之间的转换方法,其中进制到八进制(或十六进制)的转换方法称为“三位压缩成一位”(或“四位压缩成一位”),八进制(或十六进制)到进制之间的转换方法称为“一位展开成三位”(或“一位展开成四位”)。 此处详细介绍进制与八进制之间的转换方法。对于进制与十六进制之间的转换,其方法与进制与八进制之间的转换类似,只要将其中的“三”字换成“四”即可。 进制到八进制的转换分两个步骤进行,第一步转换数值的整数部分,第步转换数值的小数部分。 对于整数部分,按照三位一组,从右至左逐步将进制数字字符分组。如果最左边的一组进制不够三位,最高位填充0,直到该组包含三位进制数字。对于每组的三位进制数字表示的数,用对应的八进制数字字符替换之,就得到了整数部分的八进制表示; 对于小数部分,按照三位一组,从左至右逐步将进制数字字符分组。如果最右边一组的进制数字不够三位,最低位填充0,直到该组包含三位进制数字。同样,对于每组的三位进制数字表示的数,用等价的八进制数字字符替换之,就得到了小数部分的八进制表示。将这两部的结果合并起来,小数点的位保持不变,就产生了与该进制数等价的八进制表示。 下面的连等式显示了将进制数(1010010101.10111) 2 ​ 转换为等价八进制数的过程: (1010010101.10111) 2 ​ =(1010010101.10111) 2 ​ =(001010010101.101110) 2 ​ =(1225.56) 8 ​ 类似地,可得到该进制数的十六进制表示: (1010010101.10111) 2 ​ =(1010010101.10111) 2 ​ =(001010010101.10111000) 2 ​ =(295.B8) 16 ​ 从八进制到进制的转换很简单,只需将八进制数的每个字符代表的数值用对应的三位进制字符替代,并且小数点位不变。转换后高位0和低位0可以省略。例如,将八进制数(3745) 8 ​ 转换为对应的进制数的过程如下: (3705.426) 8 ​ =(011111000101.100010110) 2 ​ =(11111000101.10001011) 2 ​ 用类似方法,能将十六进制数(1F59.A28) 16 ​ 转换成对应的进制表示: (1F59.A28) 16 ​ =(0001111101011001.101000101000) 2 ​ =(1111101011001.101000101) 2 ​ 编程要求 本关的编程任务是补全12-1.py文件中的dec2bin_Int、dec2bin_Point以及bin2oh函数,以实现“任务描述”中的三个题目。 具体请参见后续测试样例。 本关涉及的代码文件12-1.py的代码框架如下: from random import * #第一题 def dec2bin_Int(dec): binum = &#39;&#39; # 请在此添加代码,补全函数dec2bin_Int #-----------Begin---------- #------------End----------- return binum[::-1] #第题 def dec2bin_Point(dec, length): binum = &#39;&#39; # 请在此添加代码,补全函数dec2bin_Point #-----------Begin---------- #------------End----------- return &#39;0.&#39;+binum #第三题 def bin2oh(binum, oh): result = &#39;&#39; if oh == &#39;o&#39;: # 请在此添加代码,补全函数bin2oh #-----------Begin---------- #------------End----------- return result elif oh == &#39;h&#39;: # 请在此添加代码,补全函数bin2oh #-----------Begin---------- #------------End----------- return result if __name__ == &#39;__main__&#39;: seed(0) tests = [randint(1, n) for n in [10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000]] bins = [] for num in tests: binum = dec2bin_Int(num) print(binum) bins.append(binum) print(&#39;*&#39;*30) seed(99) decimals = [] for i in range(10): decimals.append(round(random(),3)) print(decimals) for dec in decimals: print(dec2bin_Point(dec, 8)) print(&#39;*&#39; * 30) print(tests) for binum in bins: print(bin2oh(binum, &#39;o&#39;)) print(&#39;*&#39; * 30) for binum in bins: print(bin2oh(binum, &#39;h&#39;)) 测试说明 下面是对平台如何评测你所实现功能的说明及样例测试。本关的测试文件是12-1.py自身。 以下是平台对12-1.py的样例测试集: 测试输入:无输入 预期输出: 111 1110 11 100010 10000011 11111001 110011111 11101011001 100110110101 1111010000001 ****************************** [0.404, 0.2, 0.179, 0.248, 0.76, 0.251, 0.383, 0.684, 0.539, 0.938] 0.01100111 0.00110011 0.00101101 0.00111111 0.11000010 0.01000000 0.01100010 0.10101111 0.10001001 0.11110000 ****************************** [7, 14, 3, 34, 131, 249, 415, 1881, 2485, 7809] 7 16 3 42 203 371 637 3531 4665 17201 ****************************** 7 E 3 22 83 F9 19F 759 9B5 1E81任务描述 请编写一个Python程序,实现十进制整数到进制整数的转换; 请编写一个Python程序,实现十进制小数到进制小数的转换。请注意,length参数用于指定转换后进制位数; 请编写一个Python程序,实现进制整数分别到八进制和十六进制整数的转换。请注意,由参数oh来指定是转成八进制(’o’)还是十六进制(’h’)。 相关知识 一个数值能够用不同进制表示,这些表示之间存在转换关系。计算机使用进制表示数值,而人类惯用十进制。当将数值输入到计算机中时,必须将十进制转换为进制,而将计算机中的数值输出时,一般要将其转换为十进制,以便于人阅读和理解。对整数而言,虽然进制不同,但是一个数的不同进制表示在数值上是相等的,因此有: (N) 10 ​ =a n ​ ×2 n +⋯+a 1 ​ ×2 1 +a 0 ​ ×2 0 (1) 上式等号左边下标10表示用十进制表示整数N。由上式可得,将进制整数转换为十进制整数,可直接按照等号右边的式子,做十进制的乘法和加法就能完成。例如,进制整数(10111) 2 ​ 可按照上式转换为十进制整数: 1×2 4 +0×2 3 +1×2 2 +1×2 1 +1×2 0 =(23) 10 ​ 而十进制整数到进制整数的转换可采用“除2取余”法,其方法也可由上式推导出来。N代表给定的十进制整数,a n ​ 、…a 1 ​ 、a 0 ​ 分别代表需要求出的各位进制数字。(1)式等号两边同时除以2,等式保持不变。从等式右边可看出,N除以2得到的余数是a 0 ​ ,得到的商为a n ​ ×2 n−1 +⋯+a 2 ​ ×2 1 +a 1 ​ ,对商再除以2,又得余数a 1 ​ 和商a n ​ ×2 n−2 +⋯+a 3 ​ ×2 1 +a 2 ​ ,等等,依此进行下去,直到商为0。这个过程中得到的所有余数或为0 或为1,将它们按照求得的顺序的反序拼接在一起,就得到所需要的进制表示形式。 如下图1给出了将(37) 10 ​ 转换成进制的过程,所得结果为: (37) 10 ​ =(100101) 2 ​ 。 进制小数与十进制小数之间的转换方法也能通过公式推导出来。如下式所示,其中0.a-1a-2… a-m是进制小数,下标m可能为无穷大,N是等价的十进制小数,下标m可能为无穷大,N是等价的十进制小数。 (N) 10 ​ =a −1 ​ ×2 −1 +a −2 ​ ×22 ++⋯+a −m ​ ×2 −m (2) 同样地,将进制小数转换为十进制小数,可直接按照等号右边的式子,做十进制的除法和加法即可。例如,已知(0.1011) 2 ​ ,求其等价的十进制小数,转换过程为: 1×2 −1 +0×22 +1×23 +1×2 −4 =(0.6875) 10 ​ 十进制小数到进制小数的转换可采用“乘2取整”法,将公式(2)两边同时乘以2,等式仍成立,此时,右边整数部分变成a −1 ​ ,小数部分变为: a −2 ​ ×2 −1 +a −3 ​ ×22 +⋯+a −m ​ ×2 −m+1 再对结果的小数部分两边乘以2,右边整数部分变成a −2 ​ ,小数部分为: a −3 ​ ×2 −1 +⋯+a −m ​ ×2 −m+2 依此进行下去,直到乘2的结果中小数部分为0,或者达到所需要的进制位数。对于很多十进制小数,上述乘2的过程,达不到结果小数部分为0的情形。因此,十进制小数到进制小数的转换是不精确的转换。下图2中给出了十进制小数到进制小数转换的两个例子,左边是将十进制数0.625转换成进制数,它是精确转换;右边是将十进制数0.34转换成进制数,它是不精确转换。从图中可得: 从图2的例子还可知道,用进制来表示十进制数时,有些数不能精确表示,只能在表示能力范围内给出近似表示。这与可用的进制位数和十进制数自身相关: 可用的进制位数是由计算机的能力决定的,对32位计算机,可以用来表示数的位数通常有8、16和32位,位数越多,能表示的数值越多,精度也越高; 对不能精确转化为进制的十进制小数,即便能用的进制位数很多,也无法精确地表示出来。例如,0.1这个十进制小数转换成进制小数是一个无限循环小数,理论上就无法精确表示。 除了表示数值,还需表示数值的符号: 如“+”或“-”。通常用进制表示的最高位来表示数值的符号位,0表示正数、1表示负数。因此,如果能用的进制位为8位,那么,(23) 10 ​ =(00010111) 2 ​ 。 而(23) 10 ​ =(10010111) 2 ​ ,这种表示方式称为原码表示。 计算机中通常用浮点数来表示实数,浮点数是指有理数中某特定子集的数的数字表示,在计算机中用以近似表示任意的某个实数。浮点计算是指浮点数参与的运算,这种运算通常伴随着因为无法精确表示而进行的近似或舍入。考察下面的Python语句: >>>print(0.1) 0.1 >>>print("%.17lf" % 0.1) 0.10000000000000001 0.1这个十进制小数转换成进制数时,是一个无限循环小数,在计算机中通常用浮点数表示,是一种近似的表示。而现代程序设计语言的输出带有一定的智能,在保证误差较小的前提下会自动舍入。所以第一个print语句打印0.1。但是,当用第2个print语句指定输出精度时,就能看到0.1在计算机中不是真正的0.1,而是有一定的误差的。同理,浮点数之间用>、<、==来比较大小是不可取的,需要看两个浮点数是否在合理的误差范围,如果误差合理,即认为相等;否则,两个在十进制中相等的数可能在计算机中是不相等的。 此外,浮点数的误差会在其计算过程中累积,考察下面的Python程序: x = 0.0 for i in range(100): x += 0.1 print("%.17lf" % x) print(x) 运行该程序得到的输出如下所示:第1行是x的较为精确的表示,而第2行是print自动舍入,显示出来的看似正确的结果。 9.99999999999998046 10.0 八进制和十六进制是计算机领域使用的辅助计数法,用于计算机与人类的交互。八进制或十六进制与进制之间的转换很直观和简单,在认知上接近进制。这些原因促进人们引入八进制和十六进制。由于这两种进制是辅助计数方法,人们不关心对八进制数或十六进制数的运算,在此对八进制运算和十六进制的运算不进行讨论。 八进制的基本组成为: 基本数字符号有八个,分别是0、1、23、4、5、6、7; 基本符号形成字符的语法规则与进制相同; 解释合法字符的语义规则是“逢八进一”; 基本运算(不予讨论)。 2374、101、0.564、3.21和11.101等都是合法的八进制数表示,而9021、11.2.5和76+2等都不是合法的八进制数字。注意八进制(101) 8 ​ 代表的数值与进制(101) 2 ​ 代表的数值不相等,同样(11.101) 8 ​ 与(11.101) 2 ​ 不等价。 十六进制的基本组成是: 表示数的基本符号有十六个,0∽9的数字符号和A∽F的字母符号。字母A∽F分别代表数10∽15; 基本符号形成字符的语法规则与进制相同; 解释合法字符的语义规则是“逢十六进一”; 基本运算(不予讨论)。 57A8、1101、1370、901B、FFFF、E.D1C和0.ABC等都是合法的十六进制数字,而A12H、BE.12.3、A+1F等都不是合法的十六进制数(1101) 16 ​ 和(1101) 2 ​ 代表不同数值。 进制数与八进制数以及进制数与十六进制数之间有一种直接的对应关系。一位八进制能表示0∽7之间的8个数值,恰好对应3进制能表示的数值范围;一位十六进制表示0∽15之间的16个数值,恰好对应4位进制能表示的数值范围。用这种对应关系可推导出它们之间的转换方法,其中进制到八进制(或十六进制)的转换方法称为“三位压缩成一位”(或“四位压缩成一位”),八进制(或十六进制)到进制之间的转换方法称为“一位展开成三位”(或“一位展开成四位”)。 此处详细介绍进制与八进制之间的转换方法。对于进制与十六进制之间的转换,其方法与进制与八进制之间的转换类似,只要将其中的“三”字换成“四”即可。 进制到八进制的转换分两个步骤进行,第一步转换数值的整数部分,第步转换数值的小数部分。 对于整数部分,按照三位一组,从右至左逐步将进制数字字符分组。如果最左边的一组进制不够三位,最高位填充0,直到该组包含三位进制数字。对于每组的三位进制数字表示的数,用对应的八进制数字字符替换之,就得到了整数部分的八进制表示; 对于小数部分,按照三位一组,从左至右逐步将进制数字字符分组。如果最右边一组的进制数字不够三位,最低位填充0,直到该组包含三位进制数字。同样,对于每组的三位进制数字表示的数,用等价的八进制数字字符替换之,就得到了小数部分的八进制表示。将这两部的结果合并起来,小数点的位保持不变,就产生了与该进制数等价的八进制表示。 下面的连等式显示了将进制数(1010010101.10111) 2 ​ 转换为等价八进制数的过程: (1010010101.10111) 2 ​ =(1010010101.10111) 2 ​ =(001010010101.101110) 2 ​ =(1225.56) 8 ​ 类似地,可得到该进制数的十六进制表示: (1010010101.10111) 2 ​ =(1010010101.10111) 2 ​ =(001010010101.10111000) 2 ​ =(295.B8) 16 ​ 从八进制到进制的转换很简单,只需将八进制数的每个字符代表的数值用对应的三位进制字符替代,并且小数点位不变。转换后高位0和低位0可以省略。例如,将八进制数(3745) 8 ​ 转换为对应的进制数的过程如下: (3705.426) 8 ​ =(011111000101.100010110) 2 ​ =(11111000101.10001011) 2 ​ 用类似方法,能将十六进制数(1F59.A28) 16 ​ 转换成对应的进制表示: (1F59.A28) 16 ​ =(0001111101011001.101000101000) 2 ​ =(1111101011001.101000101) 2 ​ 编程要求 本关的编程任务是补全12-1.py文件中的dec2bin_Int、dec2bin_Point以及bin2oh函数,以实现“任务描述”中的三个题目。 具体请参见后续测试样例。 本关涉及的代码文件12-1.py的代码框架如下: from random import * #第一题 def dec2bin_Int(dec): binum = &#39;&#39; # 请在此添加代码,补全函数dec2bin_Int #-----------Begin---------- #------------End----------- return binum[::-1] #第题 def dec2bin_Point(dec, length): binum = &#39;&#39; # 请在此添加代码,补全函数dec2bin_Point #-----------Begin---------- #------------End----------- return &#39;0.&#39;+binum #第三题 def bin2oh(binum, oh): result = &#39;&#39; if oh == &#39;o&#39;: # 请在此添加代码,补全函数bin2oh #-----------Begin---------- #------------End----------- return result elif oh == &#39;h&#39;: # 请在此添加代码,补全函数bin2oh #-----------Begin---------- #------------End----------- return result if __name__ == &#39;__main__&#39;: seed(0) tests = [randint(1, n) for n in [10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000]] bins = [] for num in tests: binum = dec2bin_Int(num) print(binum) bins.append(binum) print(&#39;*&#39;*30) seed(99) decimals = [] for i in range(10): decimals.append(round(random(),3)) print(decimals) for dec in decimals: print(dec2bin_Point(dec, 8)) print(&#39;*&#39; * 30) print(tests) for binum in bins: print(bin2oh(binum, &#39;o&#39;)) print(&#39;*&#39; * 30) for binum in bins: print(bin2oh(binum, &#39;h&#39;)) 测试说明 下面是对平台如何评测你所实现功能的说明及样例测试。本关的测试文件是12-1.py自身。 以下是平台对12-1.py的样例测试集: 测试输入:无输入 预期输出: 111 1110 11 100010 10000011 11111001 110011111 11101011001 100110110101 1111010000001 ****************************** [0.404, 0.2, 0.179, 0.248, 0.76, 0.251, 0.383, 0.684, 0.539, 0.938] 0.01100111 0.00110011 0.00101101 0.00111111 0.11000010 0.01000000 0.01100010 0.10101111 0.10001001 0.11110000 ****************************** [7, 14, 3, 34, 131, 249, 415, 1881, 2485, 7809] 7 16 3 42 203 371 637 3531 4665 17201 ****************************** 7 E 3 22 83 F9 19F 759 9B5 1E81
最新发布
12-22
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值