计组课
该比赛已结束,您无法在比赛模式下递交该题目。您可以点击“在题库中打开”以普通模式查看和递交本题。
Description
Orange正在学习计算机组成原理(Computer Organization),他对计算机的存储系统非常感兴趣:他很好奇计算机到底是如何用二进制来存储所有信息的。
现在,Orange正在研究浮点数的存储:在现代计算机中,对于一个浮点数,我们常用一个三十二位的二进制来表示一个浮点数,我们称这种浮点数为32位浮点数(float32)。
要获取计算机中正确的浮点数二进制表示,我们遵循如下规则:
- 我们以 为例,首先我们需要将其转化成二进制的小数表示:
- 为了简化题面,我们接下来所有的数均以二进制标识。然后,我们将其转化成如下科学计数法的形式:
其中, 是一个绝对值大于 且小于 的小数(注意,这里是二进制表示), 为其调整后的指数大小。
我们以 为例子,为了得到 ,我们需要将其右移3位(除以2的3次方),为了保证数值不变,我们需要将 设置为 11(十进制下为3),即扩大 。我们可以用如下等式来观察这个过程:
-
对于符号部分,我们用一个1位二进制数来表示其正负,我们用 表示正数, 表示负数。我们把这个二进制位称之为符号位 。
-
对于 表示的部分,我们取其小数点后的部分,用一个23位的二进制数来表示,称之为尾数 。如果小数点后的部分不够23位,则用 在后面补齐到23位,如果超过了23位,则根据^舍入规则(见下文)进行舍入,保留舍入后的23位。
对于 ,我们取 的小数部分 ,其不够23位,则在后面补0直到其满23位。于是我们得到:
- 对于科学计数法的指数部分(含符号,即区分正负),我们先给其指数 加上一个定值 (十进制下表示为 ),对于得到的新数,我们将其用 8 位二进制数进行表示,我们把这部分称之为阶码 。为了简化题意,我们保证不会发生溢出的情况,即指数加上定值127后不会超过255。
对于 ,其指数部分为 ,其加上 后为 。
- 将最终得到的三部分按照 , 和 的顺序进行拼接,得到一个32位二进制数:
这就是十进制数 在计算机中存储的形式。
7.对于一些特殊值:
- :由于其无法表示为 的形式,例如 ,我们规定用来表示,其中 为 , 为 。
- : 无穷大。我们规定来表示,用 来区分正无穷大和负无穷大。
- : 非数。由 和一个非零的 表示。符号位可以是 或 。为了简化题意,我们这里特别规定,用 ,来表示。
^舍入规则:
由于单精度浮点数的尾数只有23位,许多十进制小数(如0.1)在二进制中是无限循环的,无法被精确存储。此时,必须进行舍入。舍入的对象是规格化后的24位有效数字(隐含的
1.+ 23位尾数)之后的位数。规则:
- 观察第24位及之后的二进制位。
- 如果这些位的值大于二进制的
0.1(即第24位是1,且其后还有1),则向“上”舍入(即第23位加1)。- 如果这些位的值小于二进制的
0.1(即第24位是0),则向“下”舍入(即直接截断)。- 如果这些位的值正好等于二进制的
0.1(即第24位是1,且其后所有位都是0),此时为“平局”情况。规则是向偶数舍入:
- 如果第23位是
0(偶数),则向“下”舍入(保持第23位为0)。- 如果第23位是
1(奇数),则向“上”舍入(将第23位加1,使其变为0,并向前进位)。示例 1:常规舍入(非平局) 以
0.1为例:
0.1的二进制表示为0.000110011001100110011001100...- 规格化后为
1.10011001100110011001100(1100...) × 2^-4。- 我们需要保留24位有效数字(
1.+ 23位尾数)。当前24位是1.10011001100110011001100。- 观察第24位及之后,是
1100...,其值大于0.1。- 因此,需要向“上”舍入,将第23位(最后一个
0)加1,变为1。- 最终的尾数部分为
10011001100110011001101。- 指数
E = -4,偏移后Exp = -4 + 127 = 123(01111011)。- 符号位
S = 0。- 组合并转换为十六进制,得到
3DCCCCCD。示例 2:向偶数舍入(平局情况) 假设有一个正数,其真实二进制规格化形式为
1.0101010101010101010101010 1000... × 2^E。
- 这里的
0101010101010101010101010是前23位尾数,第23位是0。- 第24位是
1,且其后全是0。这构成了平局。- 由于第23位是
0(偶数),我们向“下”舍入,保持尾数不变。- 最终的尾数部分为
01010101010101010101010。再假设另一个正数,其真实二进制规格化形式为
1.0101010101010101010101011 1000... × 2^E。
- 这里的
0101010101010101010101011是前23位尾数,第23位是1。- 第24位是
1,且其后全是0。这构成了平局。- 由于第23位是
1(奇数),我们向“上”舍入,第23位加1并进位。- 最终的尾数部分变为
01010101010101010101100。
现在,Orange将给定一个十进制数,请你编写一个程序,将其转换为等价的32位计算机存储表示,并以8位大写十六进制字符串的形式输出。
Format
Input
输入的第一行包含一个整数 ,表示测试用例的数量。 接下来的 行,每行包含一个字符串,表示一个十进制数。该字符串可以是:
- 一个标准十进制数(例如,
12.375,-0.03125)。 - 一个科学计数法表示的数(例如,
1.23e-4,3e8)。 - 一个特殊值:
inf,-inf,nan,0,-0。 保证所有输入都是合法的,并且在单精度浮点数可表示的范围内。每个输入字符串的长度不超过50个字符。
Output
对于每个测试用例,输出一行,包含一个8位的大写十六进制字符串,表示给定数字的计算机存储编码。如果需要,应包含前导零。
Samples
8
12.375
-0.03125
0.1
0
-0
inf
-inf
nan
414C0000
BE000000
3DCCCCCD
00000000
80000000
7F800000
FF800000
7FC00000
Note
12.375:- 二进制:
1100.011 - 规格化:
1.100011 × 2^3 - 符号位(S) = 0, 指数(E) = 3。偏移指数 Exp = 3 + 127 = 130 (
10000010)。 - 小数部分 =
100011后跟18个0。 - 比特序列:
0 10000010 10001100000000000000000 - 十六进制:
414C0000
- 二进制:
-0.03125:- 二进制:
0.00001 - 规格化:
1.0 × 2^-5 - 符号位(S) = 1, 指数(E) = -5。偏移指数 Exp = -5 + 127 = 122 (
01111010)。 - 小数部分 = 23个0。
- 比特序列:
1 01111010 00000000000000000000000 - 十六进制:
BE000000
- 二进制:
0.1无法在二进制中精确表示。其在单精度浮点数中最接近的可表示值为3DCCCCCD。0是正零,因此所有位都为0。十六进制:00000000。-0是负零,因此符号位为1,其余位为0。十六进制:80000000。inf是正无穷。符号位=0, 指数=255, 小数=0。十六进制:7F800000。-inf是负无穷。符号位=1, 指数=255, 小数=0。十六进制:FF800000。nan是一个非数值。符号位=0, 指数=255, 小数部分为1(C00000)。十六进制:7FC00000。