IEEE754浮点数标准

什么是 IEEE

电气电子工程师学会(英语:Institute of Electrical and Electronics Engineers,简称为IEEE),是一个建立于196311日的国际性电子技术与电子工程师协会,亦是世界上最大的专业技术组织之一,拥有来自175个国家的42万会员。总部设立于:美国纽约市。目前IEEE在工业界所定义的标准有着极大的影响

IEEE 都发布了哪些标准?

标准代号说明
IEEE 754浮点算法规范
IEEE 802局域网和广域网
IEEE 802.11无限网络
IEEE 802.16无限宽频网络
IEEE 829软件测试文书
IEEE 896未来总线Futurebus
IEEE 1003POSIX(可移植操作系统接口)
IEEE 1076VHDL(VHSIC硬件描述语言)
IEEE 1149.1JTAG
IEEE 1275Open Firmware
IEEE 1284并口
IEEE P1363公钥密码
IEEE 1364Verilog 硬件描述语言
IEEE 1394窜行总线“火线”
IEEE 1619存储安全
IEEE 1901PLC
IEEE 12207软件生命周期过程
IEEE 1275Open Firmware

IEEE754 标准解释

这是IEEE754标准的一张图

ieee754.pngieee754.png

S: 符号位 (0:整数 1:负数)
E: 阶码部分 (单精度:8bit,双精度:11bit)
M: 尾数部分 (单精度:23bit,双精度:52bit)

实战

十进制数字:123.25
二进制表示:
整数部分:1111011
小数部分:01
完整表示:1111011.01
科学记数法:1.11101101 2*6 (2的6次方)

结果:
S: 0 = 0
E:6(指数) + 1023(偏移量) = 1029 = 10000000101
M: 11101101

结合起来二进制表示:
010000000010111101101000000000000000000...(不够64位就用0填充)

image.pngimage.png

学习地址

缓存一致性协议-mesi

背景

现代CPU几乎都是多核,每个核心也有自己独立的缓存(L1,L2,L3),当多个核心同时对一个数据(变量)更新时,假设核心1在核心2还未将更新的数据刷回内存之前读取了数据,并进行操作就会造成程序执行的结果不符合逾期。这对于我们程序来说,是不正确的。

字母解释

  • M:(modify)修改 -- 该缓存行有效,数据被修改了,和内存中的数据不一致,数据只存在于本缓存行中
  • E:(exclusive)独享、互斥 -- 该缓存行有效,数据和内存中的数据一致,数据只存在于本缓存行中
  • S:(shared)共享 -- 该缓存行有效,数据和内存中的数据一致,数据同时存在于其他缓存中
  • I:(invalid)无效 -- 该缓存行数据无效

优势

对于总线锁,总线锁是对整个内存进行加锁,在一个核心对一个数据进行修改的过程中,其他的核心也无法修改内存中的其他数据,这样会导致CPU处理性能严重下降。

什么情况下不可用

  1. CPU不支持缓存一致性协议
  2. 变量超过一个缓存行的大小,缓存一致性协议是针对单个缓存进行加锁。此时,缓存一致性协议无法再对该变量进行加锁,只能改用总线加锁方式。

wsl 使用实践

wsl 使用实践

wsl 是什么

wsl 全称 windows subsystem for linux,是一个可以运行在 windows 10 系统之上的,完整的 ubuntu 操作系统。

常用命令

  • wsl --list --online 列出可用的 linux 发行版

    NAME            FRIENDLY NAME
    Ubuntu          Ubuntu
    Debian          Debian GNU/Linux
    kali-linux      Kali Linux Rolling
    openSUSE-42     openSUSE Leap 42
    SLES-12         SUSE Linux Enterprise Server v12
    Ubuntu-16.04    Ubuntu 16.04 LTS
    Ubuntu-18.04    Ubuntu 18.04 LTS
    Ubuntu-20.04    Ubuntu 20.04 LTS

用go语言写的一个贪吃蛇小游戏

go-snake

游戏由来

因想给儿子写一款小游戏,就想到了用 go 写一个贪吃蛇的游戏。游戏引擎使用的是 ebiten, 它是一款 2d 的游戏引擎。
现在这个游戏只完成一些基础部分的编写,整体是能运行起来,对于一些更具体的游戏玩法和人机互动功能还未完善,后面时间多的情况下,我会逐步去完善它,添加更多的游戏交互效果。
这个游戏也让想学习 ebiten 引擎的同学提供了一些参考。

项目地址

https://github.com/AaronChengHao/gosnake

这是游戏中的截图

imageimage

这是游戏的 gif

imageimage

通过 unsafe.Pointer 验证切片是引用类型

看过很多文章,都说切片(slice)是引用类型, 但是实际操作中很难通过结果来证明是引用类型,特别是使用 append 函数时,打印切片结果还是没有变化。 现在我们来使用 unsafe.Pointer 来修改切换的 len 属性来证明切片是引用类型。 废话不多说,上代码...

package main

import (
    "fmt"
    "reflect"
    "unsafe"
)

func main() {
    s := make([]int, 0, 5)
    // 初始化切片数据
    s = append(s, 1, 2, 3)

    // 调用appendSlice方法,给切片添加数据
    appendSlice(s)

    // 打印切片
    fmt.Println(s) // 输出:1 2 3 (说明增加的 100 没有在这儿体现出来)

    // 现在我们来使用黑科技,来证明切片是引用类型
    sh := (*reflect.SliceHeader)(unsafe.Pointer(&s))
    sh.Len = 4

    // 现在重新打印
    fmt.Println(s) // 输出: 1 2 3 100 (现在看到100, 是不是就是说明 appendSlice 方法的修改,已经影响到了外面的slice了,也就证实了slice是引用类型哦)
}

func appendSlice(s []int) {
    s = append(s, 100)
}

补充说明
注意,追加的切片数据不能超过容量哦,不然会引起切片底层数组指针指向新的数组地址,那就不能看出效果了。