IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 为什么 0.1+0.2=0.30000000000000004 -> 正文阅读

[Python知识库]为什么 0.1+0.2=0.30000000000000004

作者:https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/markdown_views-3fd7f7a902.css

在这里插入图片描述

图1

在这里插入图片描述

图2

0.1 和 0.2 是如何表示的?
根据前面的讲解,十进制 0.1 转为二进制小数,得到的是 0.0001100… (重复1100)这样一个循环二进制小数,使用 IEEE754 表示如下图:

在这里插入图片描述

图3

对这个 0.1 的二进制数据进行二进制编码,

再对这个编码进行切割,怎么切割呢,从左向右找,找到 第一个 1 就一刀砍下去,将这么长长的数切割成两端
0001100110011001100110011001100110011001100110011001101
指数尾数
0001100110011001100110011001100110011001100110011001101

可以发现前面有四位,是 0001 ,那么这个浮点数的指数就是 -4 ,为什么是负数呢,应为这是小数,是向右数数,

上面第二张图可以看出,浮点数的指数位有8个比特 ,一共可以表达 2 8 = 256 2^8=256 28=256数,float 类型既要表达绝对值很大大数或者很小的数, 0 和 255 对应两种特殊情况,编码1-254则依次对应 指数范围 -126-127

十进制指数浮点数八位指数十进制编码浮点数八位指数二进制编码
-12610000 0001
-12520000 0010
-41230111 1011
11281000 0000
1272541111 1110
也就是说,图2 里面的二进制编码 为 127+(-4)=123 =0111 1011
指数23位尾数舍入项截断项
0001100110011001100110011001100110011001100110011001101
第一个 1 分割尾数最后一项是0,但是舍入项是0.75,需要进1 1 ? ( 0.5 ) ? 1 + 1 ? ( 0.5 ) ? 2 + 0 ? ( 0.5 ) ? 3 + 0 ? ( 0.5 ) ? 4 = 0.75 1*(0.5)^{-1}+1*(0.5)^{-2}+0*(0.5)^{-3}+0*(0.5)^{-4}=0.75 1?(0.5)?1+1?(0.5)?2+0?(0.5)?3+0?(0.5)?4=0.75
10011001100110011001101

在浮点数的舍入问题上,IEEE 浮点格式定义了 4 种不同的舍入方式,如下表所示。其中,默认的舍入方法是向偶数舍入,而其他三种可用于计算上界和下界。

其次我们来考虑尾数 ,位数占用23 个比特,如果你直接在尾数 截取23 个比特,那么 用浮点数将永远小于我们需要表达的数,你把一条龙的一个小尾巴截了,龙的体重一定是变轻了。所以一定要加入舍入规则,这里不是简单的四舍五入 而是 四舍六入五成双,舍入细节请看 四舍六入五成双

同样的方法,0.2 用单精度浮点数表示是:0.20000000298023223876953125。所以,0.1 + 0.2 的结果是:0.300000004470348358154296875

在这里插入图片描述

用 python 代码 来实现


#将十进制小数转化为二进制
def dec2bin(x):
  x -= int(x)
  bins = []
  while x:
    x *= 2
    bins.append(1 if x>=1. else 0)
    x -= int(x)
  return bins
#print()

#cc=dec2bin(0.1)

0.1 的二进制表示

cc1=dec2bin(0.1)
#cc1=0001100110011001100110011001100110011001100110011001101

0.2 的二进制表示

cc2=dec2bin(0.2)
#cc1=001100110011001100110011001100110011001100110011001101

全部代码

# -*- coding: utf-8 -*-
"""
Created on Thu Jun  9 17:20:29 2022

@author: luogantt
"""

import numpy as np

#将十进制小数转化为二进制
def dec2bin(x):
  x -= int(x)
  bins = []
  while x:
    x *= 2
    bins.append(1 if x>=1. else 0)
    x -= int(x)
  return bins
print(dec2bin(.8125))


def expo(cc):
   
    n=0
    while (not cc[n]):
        n=n+1
        print(n)
    return n+1



"""
  >0.5           --1
  <0.5           --0
  ==0.5 if up==0 --0
  ==0.5 if up==1 --1 
"""

#决定舍入项是否要进一位
def roundings(cc,exp):
    drop= np.array(cc[exp+23:exp+23+4])
    weight=np.array([1/2,1/4,1/8,1/16])
    
    ifdrop=np.sum(weight*drop)
    
    if ifdrop>0.5:
        return 1
    elif  ifdrop<0.5:
        return 0
    else:
        if cc[exp+23]==0:
            return 0
        else:
            return 1 
        
        

# 将小数位转换成 float32 
def float32(exp,cc):
    
    fric=cc[exp:exp+23]
    
    strfric=''.join([str(k) for k in fric])
    intfric= int(strfric,2)
    
    round1= roundings(cc,exp)
    
    if round1:
        intfric=intfric+1
    
    intfric1=bin(intfric)
    intfric2=intfric1[2:]
    
    intfric3=[int(k) for k in intfric2]
    
    sum=0
    for k in range(len(intfric3)):
        sum=sum+intfric3[k]*2**(-1*(k+exp+1))
    sum=sum+(2)**(-(exp))
        
    print(sum)
    
    return sum



cc1=dec2bin(0.1)
exp1=expo(cc1)
sum1= float32(exp1,cc1)
print( '小数位',sum1)

cc2=dec2bin(0.2)
exp2=expo(cc2)
sum2= float32(exp2,cc2)
print(sum2)
#
print('0.1+0.2=',sum1+sum2)

[1, 1, 0, 1]
1
2
3
0.10000000149011612
小数位 0.10000000149011612
1
2
0.20000000298023224
0.20000000298023224
0.1+0.2= 0.30000000447034836
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章           查看所有文章
加:2022-06-16 21:39:44  更:2022-06-16 21:41:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 3:50:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计