整数和浮点数

整数和浮点数的区别:
   
整数是指正整数、负整数和零,如-6、0、32 等。
    浮点数是指带有有限位小数的有理数,如-10.8、0.00、25.01 等。
    整数既可以是整数,也可以是浮点数,例如255 是整数,而255.0 则是浮点数。
    整数运算,得到的结果是一个整数,并且计算结果中的小数部分将被忽略。例如:用整数运算时,100÷3=33。
    浮点运算,得到的结果是一个浮点数,计算结果中的小数部分将保留下来。
    例如:用浮点运算时,100.0÷3.0=33.33333333。
   

浮点数的表示方法
   
   
  浮点数,是指小数点在数据中的位置可以左右移动的数据。它通常被表示成:
    N = M* RE
   
      这里的M(Mantissa)被称为浮点数的尾数,R(Radix)被称为阶码的基数,E(Exponent)被称为阶的阶码。计算机中一般规定R为2、8或16、是一个确定的常数,不需要在浮点数中明确表示出来。因此,要表示浮点数,一是要给出尾数M的值,通常用定点小数形式表示,它决定了浮点数的表示精度,即可以给出的有效数字的位数。二是要给出阶码,通常用整数形式表示,它指出的是小数点在数据中的位置,决定了浮点数的表示范围。浮点数也要有符号位。在计算机中,浮点数通常被表示成如下格式:
   

   

 
   
   
  Ms是尾数的符号位,即浮点数的符号位,安排在最高一位;
      E 是阶码,紧跟在符号位之后,占用m位,含阶码的一位符号;
      M 是尾数,在低位部分,占用n位。

   
      合理地选择m和n的值是十分重要的,以便在总长度为1+m+n个二进制表示的浮点数中,既保证有足够大的数值范围,又保证有所要求的数值精度。例如,在PDP-11/70计算机中,用32位表示的一个浮点数,符号位占一位,阶码用8位,尾数用23位,数的表示范围约为±1.7*10±38,精度约为10进制的7位有效数字。
   
      若不对浮点数的表示格式作出明确规定,同一个浮点数的表示就不是唯一的。例如0.5也可以表示为0.05×101 , 50×10-2 等。为了提高数据的表示精度,也为了便于浮点数之间的运算与比较,规定计算机内浮点数的尾数部分用纯小数形式给出,而且当尾数的值不为0时,其绝对值应大于或等于0.5,这被称为浮点数的规格化表示。对不符合这一规定的浮点数,要通过修改阶码并同时左右移尾数的办法使其变成满足这一要求的表示形式,这种操作被称为的规格化处理,对浮点数的运算结果就经常需要进行规格化处理。
   
      当一个浮点数的尾数为0,不论其阶码为何值,该浮点数的值都为0。当阶码的值为它能表示的最小一个值或更小的值时,不管其尾数为何值,计算机都把该浮点数看成零值,通常称其为机器零,此时该浮点数的所有各位(包括阶码位和尾数位)都清为0值。
   
     按国际电子电气工程师协会的IEEE标准,规定常用的浮点数的格式为:
   
           符号位  阶码  尾数  总位数
      短浮点数   1    8   23   32
      长浮点数   1    11   52   64
      临时浮点数  1    15   64   80
   
   
  对短浮点数和长浮点数,当其尾数不为0值时,其最高一位必定为1,在将这样的浮点数写入内存或磁盘时,不必给出该位,可左移一位去掉它,这种处理技术称为隐藏位技术,目的是用同样多位的尾数能多保存一位二进制位。在将浮点数取回运算器执行运算时,再恢复该隐藏位的值。对临时浮点数,不使用隐藏位技术
   
   
  从上述讨论可以看到,浮点数比定点小数和整数使用起来更方便。例如,可以用浮点数直接表示电子的质量9×10-28 克,太阳的质量2×1033 克,圆周率3.1416等。上述值都无法直接用定点小数或整数表示,要受数值范围和表示格式各方面的限制。

 


 

什么是浮点数

    在计算机系统的发展过程中,曾经提出过多种方法表达实数。典型的比如相对于浮点数的定点数(Fixed Point Number。在这种表达方式中,小数点固定的位于实数所有数字中间的某个位置。货币的表达就可以使用这种方式,比如 99.00 或者 00.99 可以用于表达具有四位精度(Precision),小数点后有两位的货币值。由于小数点位置固定,所以可以直接用四位数值来表达相应的数值。SQL 中的NUMBER 数据类型就是利用定点数来定义的。还有一种提议的表达方式为有理数表达方式,即用两个整数的比值来表达实数。

 

    定点数表达法的缺点在于其形式过于僵硬,固定的小数点位置决定了固定位数的整数部分和小数部分,不利于同时表达特别大的数或者特别小的数。最终,绝大多数现代的计算机系统采纳了所谓的浮点数表达方式。这种表达方式利用科学计数法来表达实数,即用一个尾数(Mantissa ),一个基数(Base),一个指数(Exponent)以及一个表示正负的符号来表达实数。比如 123.45 用十进制科学计数法可以表达为 1.2345 × 102,其中 1.2345 为尾数,10为基数,2 为指数。浮点数利用指数达到了浮动小数点的效果,从而可以灵活地表达更大范围的实数。

 

提示: 尾数有时也称为有效数字(Significand)。尾数实际上是有效数字的非正式说法。

 

    同样的数值可以有多种浮点数表达方式,比如上面例子中的 123.45 可以表达为12.345 × 1010.12345×103或者 1.2345 ×102。因为这种多样性,有必要对其加以规范化以达到统一表达的目标。规范的(Normalized)浮点数表达方式具有如下形式:

 

±d.dd...d × β e , (0 d i < β)

 

    其中 d.dd...d 即尾数,β 为基数,e 为指数。尾数中数字的个数称为精度,在本文中用 p 来表示。每个数字 d 介于 0 和基数之间,包括 0。小数点左侧的数字不为 0

 

基于规范表达的浮点数对应的具体值可由下面的表达式计算而得:

 

±(d 0 + d 1β-1 + ... + dp-1β-(p-1))β e , (0 d i < β)

 

    对于十进制的浮点数,即基数 β 等于 10 的浮点数而言,上面的表达式非常容易理解,也很直白。计算机内部的数值表达是基于二进制的。从上面的表达式,我们可以知道,二进制数同样可以有小数点,也同样具有类似于十进制的表达方式。只是此时 β 等于2,而每个数字 d 只能在0 1 之间取值。比如二进制数 1001.101 相当于 1 ×2 3 + 0 ×2 2 + 0 ×2 1 + 1 × 2 1 + 1 ×2 -1 + 0 ×2 -2 + 1 ×2 -3,对应于十进制的 9.625。其规范浮点数表达为 1.001101 ×2 3

 

2. IEEE 浮点数

    计算机中是用有限的连续字节保存浮点数的。保存这些浮点数当然必须有特定的格式,Java平台上的浮点数类型 float  double 采纳了 IEEE754 标准中所定义的单精度32 位浮点数和双精度64 位浮点数的格式。

注意Java平台还支持该标准定义的两种扩展格式,即float-extended-exponent double-extended-exponent 扩展格式。这里将不作介绍,有兴趣的读者可以参考相应的参考资料。

    IEEE 标准中,浮点数是将特定长度的连续字节的所有二进制位分割为特定宽度的符

号域,指数域和尾数域三个域,其中保存的值分别用于表示给定二进制浮点数中的符号,指数和尾数。这样,通过尾数和可以调节的指数(所以称为"浮点")就可以表达给定的数值了。具体的格式参见下面的图例:

单精度浮点数

   

signexponentmantissa
1 bit8 bits23 bit

在上面的图例中,第一个域为符号域。其中 0 表示数值为正数,而 1 则表示负数。

    第二个域为指数域,对应于我们之前介绍的二进制科学计数法中的指数部分。其中单精度数为 8 位,双精度数为 11 位。以单精度数为例,8 位的指数为可以表达 0 255 之间的 255 个指数值。但是,指数可以为正数,也可以为负数。为了处理负指数的情况,实际的指数值按要求需要加上一个偏差(Bias)值作为保存在指数域中的值,单精度数的偏差值为 127,而双精度数的偏差值为 1023。比如,单精度的实际指数值 0 在指数域中将保存为 127;而保存在指数域中的 64 则表示实际的指数值 -63偏差的引入使得对于单精度数,实际可以表达的指数值的范围就变成-127 128 之间(包含两端)。我们不久还将看到,实际的指数值-127(保存为 0)以及 +128(保存为全 1)保留用作特殊值的处理。这样,实际可以表达的有效指数范围就在 -127 127 之间。在本文中,最小指数和最大指数分别用 emin  emax 来表达

    图例中的第三个域为尾数域,其中单精度数为 23 位长,双精度数为 52 位长。除了我们将要讲到的某些特殊值外,IEEE 标准要求浮点数必须是规范的。这意味着尾数的小数点左侧必须为 1,因此我们在保存尾数的时候,可以省略小数点前面这个1,从而腾出一个二进制位来保存更多的尾数。这样我们实际上用 23 位长的尾数域表达了 24 位的尾数。比如对于单精度数而言,二进制的 1001.101(对应于十进制的 9.625)可以表达为1.001101 × 23,所以实际保存在尾数域中的值为 00110100000000000000000,即去掉小数点左侧的 1,并用 0 在右侧补齐。

    值得注意的是,对于单精度数,由于我们只有 24 位的指数(其中一位隐藏),所以可以表达的最大指数为224 - 1 = 16,777,215。特别的,16,777,216 是偶数,所以我们可以通过将它除以 2 并相应地调整指数来保存这个数,这样16,777,216 同样可以被精确的保存。相反,数值16,777,217 则无法被精确的保存。由此,我们可以看到单精度的浮点数可以表达的十进制数值中,真正有效的数字不高于 8 。事实上,对相对误差的数值分析结果显示有效的精度大约为 7.22 位。参考下面的示例:

         true value                 stored value
         --------------------------------------
         16,777,215                 1.6777215E7
         16,777,216                 1.6777216E7
         16,777,217                 1.6777216E7
         16,777,218                 1.6777218E7
         16,777,219                 1.677722E7
         16,777,220                 1.677722E7
         16,777,221                 1.677722E7
         16,777,222                 1.6777222E7
         16,777,223                 1.6777224E7
         16,777,224                 1.6777224E7
         16,777,225                 1.6777224E7
         --------------------------------------

根据标准要求,无法精确保存的值必须向最接近的可保存的值进行舍入。这有点像我们熟悉的十进制的四舍五入,即不足一半则舍,一半以上(包括一半)则进。不过对于二进制浮点数而言,还多一条规矩,就是当需要舍入的值刚好是一半时,不是简单地进,而是在前后两个等距接近的可保存的值中,取其中最后一位有效数字为零者。从上面的示例中可以看出,奇数都被舍入为偶数,且有舍有进。我们可以将这种舍入误差理解为"半位"的误差。所以,为了避免 7.22 对很多人造成的困惑,有些文章经常以7.5 位来说明单精度浮点数的精度问题。

提示这里采用的浮点数舍入规则有时被称为舍入到偶数(Roundto Even)。相比简单地逢一半则进的舍入规则,舍入到偶数有助于从某些角度减小计算中产生的舍入误差累积问题。因此为IEEE 标准所采用。

实数和浮点数之间的变换

    现在我们已经明白了浮点数的 IEEE 表达方式。我们来做些实数和浮点数之间的变换练习以加深理解。在这些练习中,你还会发现一些围绕浮点数运算的令人吃惊的事实。

    首先我们来看看事情简单的一面,从浮点数变换到实数。理解了浮点数的格式,做这个练习并不难。假定我们有一个 32 位的数据,用十六进制表示为0xC0B40000,并且我们知道它实际上是一个单精度的浮点数。为了得到该浮点数实际表达的实数,我们首先将它变换为二进制形式:

   C     0     B     4     0     0     0     0
  1100  0000  1011  0100  0000  0000  0000  0000

接着按照浮点数的格式切分为相应的域:

1   10000001 01101000000000000000000

符号域 1 意味着负数;指数域为 129 意味着实际的指数为 2 (减去偏差值 127);尾数域为 01101 意味着实际的二进制尾数为 1.01101(加上隐含的小数点前面的1)。所以,实际的实数为:

-1.01101 × 22
-(20 + 2-2 + 2-3 2-5) × 22
-5.625

    实数向浮点数变换稍微麻烦一点。假定我们需要将实数-9.625 表达为单精度的浮点数格式。方法是首先将它用二进制浮点数表达,然后变换为相应的浮点数格式。

    首先,将小数点左侧的整数部分变换为其二进制形式,9 的二进制性形式为 1001。处理小数部分的算法是将我们的小数部分乘以基数2,记录乘积结果的整数部分,接着将结果的小数部分继续乘以2,并不断继续该过程:

0.625 × 2 = 1.25          1
0.25   × 2 = 0.5          0
0.5    × 2 = 1            1
0

    当最后的结果为零时,结束这个过程。这时右侧的一列数字就是我们所需的二进制小数部分,即 0.101。这样,我们就得到了完整的二进制形式1001.101。用规范浮点数表达为1.001101 × 23

    因为是负数,所以符号域为 1。指数为 3,所以指数域为 3 + 127= 130,即二进制的10000010。尾数省略掉小数点左侧的1 之后为 001101,右侧用零补齐。最终结果为:

1 10000010 00110100000000000000000

最后可以将浮点数形式表示为十六进制的数据如下:

1100    0001  0001  1010  0000  0000  0000  0000
 C     1     1     A     0     0     0     0

最终结果为 0xC11A0000

    很简单?等等!你可能已经注意到了,在上面这个我们有意选择的示例中,不断的将产生的小数部分乘以2 的过程掩盖了一个事实。该过程结束的标志是小数部分乘以 2 的结果为 1,不难想象,很多小数根本不能经过有限次这样的过程而得到结果(比如最简单的0.1。我们已经知道浮点数尾数域的位数是有限的,为此,浮点数的处理办法是持续该过程直到由此得到的尾数足以填满尾数域之后对多余的位进行舍入。换句话说,除了我们之前讲到的精度问题之外,十进制到二进制的变换也并不能保证总是精确的,而只能是近似值。事实上,只有很少一部分十进制小数具有精确的二进制浮点数表达。再加上浮点数运算过程中的误差累积,结果是很多我们看来非常简单的十进制运算在计算机上却往往出人意料。这就是最常见的浮点运算的"不准确"问题。参见下面的 Java 示例:

System.out.print("34.6-34.0=" + (34.6f-34.0f));

这段代码的输出结果如下:

34.6-34.0=0.5999985

    产生这个误差的原因是 34.6 无法精确的表达为相应的浮点数,而只能保存为经过舍入的近似值。这个近似值与34.0 之间的运算自然无法产生精确的结果。

 

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以使用内置函数int()和float()将列表中的字符串转换为整数浮点数。 示例代码: ```python str_list = ['1', '2', '3.14'] int_list = [int(x) for x in str_list] # 将字符串列表转换为整型列表 float_list = [float(x) for x in str_list] # 将字符串列表转换为浮点型列表 print(int_list) # [1, 2, 3] print(float_list) # [1.0, 2.0, 3.14] ``` 上述代码中,使用列表推导式分别将字符串列表转换为整型列表和浮点型列表,分别使用int()和float()函数进行数据类型转换,然后将结果存储在int_list和float_list中。 ### 回答2: 要将列表中的字符串转为整数浮点数,可以使用Python中的内置函数int()和float()。这两个函数分别可以将字符串转化为整数浮点数。 对于整数的转换,可以使用int()函数。该函数能够将字符串转换为整数,但是需要注意的是,被转换的字符串必须表示一个合法的整数。如果字符串不符合整数的格式,则会抛出ValueError的异常。 对于浮点数的转换,可以使用float()函数。这个函数可以将字符串转换为浮点数,但是同样需要确保被转换的字符串是符合浮点数的格式。如果字符串不符合浮点数的格式,则会抛出ValueError的异常。 要将一个列表中的所有字符串都转为整数,可以使用循环遍历列表的每个元素,并分别调用int()函数进行转换。转换后的整数可以存储在一个新列表中,或者直接替换原来的字符串元素。 对于将列表中的字符串转为浮点数,同样可以使用循环遍历列表中的每个元素,并分别调用float()函数进行转换。转换后的浮点数可以存储在一个新列表中,或者直接替换原来的字符串元素。 需要注意的是,在进行字符串到整数浮点数的转换时,一定要确保被转换的字符串是合法的整数浮点数格式,否则会抛出异常。否则,可以通过try-except语句来捕获异常并进行相应的处理。 ### 回答3: 要将列表中的字符串转为整数浮点数,我们可以使用内置的int()和float()函数。 对于整数的转换,我们可以使用int()函数,它会将字符串转化为整数。例如,假设有一个包含字符串的列表lst,我们可以使用列表推导式来将每个字符串转化为整数,并创建一个包含转换后整数的新列表new_list: new_list = [int(x) for x in lst] 对于浮点数的转换,我们可以使用float()函数,它会将字符串转化为浮点数。同样,我们可以使用列表推导式将每个字符串转化为浮点数,并创建一个包含转换后浮点数的新列表new_list: new_list = [float(x) for x in lst] 需要注意的是,使用这两个函数进行转换时,字符串必须是合法的整数浮点数表示。否则,会抛出异常。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值