go语言基础之浮点数

这里写目录标题

  • go语言基础之浮点数
    • 小数的浮点表示法
    • IEEE754标准
    • 32位单精度浮点数在内存中的存储方式
      • 符号位: sign ,即图中蓝色的方块
      • 偏移后的指数位: biased exponent, 即图中绿色的方块
      • 尾数位:fraction , 即图中红色的方块
    • 实验

小数的浮点表示法

±x.yz*e±pq

IEEE754标准

32位单精度浮点数在内存中的存储方式

存储一个32位浮点数, 比如20.5, 在内存或硬盘中要占用32个二进制位,这32个二进制位被划分为3部分

这32个二进制位的内存编号从高到低 (从31到0), 共包含如下几个部分:

符号位: sign ,即图中蓝色的方块

​ 符号位: 占据最高位(第31位)这一位, 用于表示这个浮点数是正数还是负数, 为0表示正数, 为1表示负数

偏移后的指数位: biased exponent, 即图中绿色的方块

​ 这部分用于表示以2位底的指数, IEEE754规定, 指数位用于表示[-127, 128]范围内的指数。不过为了表示起来更方便, 浮点型的指数位都有一个固定的偏移量(bias), 用于使 指数 + 这个偏移量 = 一个非负整数.。这样指数位部分就不用为如何表示负数而担心了。 在32位单精度类型中, 这个偏移量是127. 在64位双精度类型中, 偏移量是1023。所以, 这里的偏移量是127。即, 如果你运算后得到的指数是 -127, 那么偏移后, 在指数位中就需要表示为: -127 + 127(偏移量) = 0

如果你运算后得到的指数是 -10, 那么偏移后, 在指数位中需要表示为: -10 + 127(偏移量) = 117,有了偏移量, 指数位中始终都是一个非负整数.

尾数位:fraction , 即图中红色的方块

​ 尾数位: 占据剩余的22位到0位这23位. 用于存储尾数.

在以二进制格式存储十进制浮点数时, 首先需要把十进制浮点数表示为二进制格式, 还拿十进制数20.5举例:

十进制浮点数20.5 = 二进制10100.1

然后, 需要把这个二进制数转换为以2为底的指数形式:

二进制10100.1 = 1.01001 * 2^4

注意转换时, 对于乘号左边, 加粗的那个二进制数1.01001, 需要把小数点放在左起第一位和第二位之间. 且第一位需要是个非0数. 这样表示好之后, 其中的1.01001就是尾数.

我们再来看看规范化之后的这个数: 1.01001 * 2^4

其中1.01001是尾数, 而4就是偏移前的指数(unbiased exponent), 上文讲过, 32位单精度浮点数的偏移量(bias)为127, 所以这里加上偏移量之后, 得到的偏移后指数(biased exponent)就是 4 + 127 = 131, 131转换为二进制就是1000 0011

现在还需要对尾数做一些特殊处理

隐藏高位1.

尾数部分的最高位始终为1. 比如这里的 **1.**01001, 这是因为前面说过, 规范化之后, 尾数中的小数点会位于左起第一位和第二位之间. 且第一位是个非0数. 而二进制中, 每一位可取值只有0或1, 如果第一位非0, 则第一位只能为1. 所以在存储尾数时, 可以省略前面的 1和小数点. 只记录尾数中小数点之后的部分, 这样就节约了一位内存. 所以这里只需记录剩余的尾数部分: 01001

所以, 以后再提到尾数, 如无特殊说明, 指的其实是隐藏了整数部分1. 之后, 剩下的小数部分

低位补0

​ 有时候尾数会不够填满尾数位(即图中的红色格子). 比如这里的, 尾数01001不够23位。此时, 需要在低位补零, 补齐23位.之所以在低位补0, 是因为尾数中存储的本质上是二进制的小数部分, 所以如果想要在不影响原数值的情况下, 填满23位, 就需要在低位补零。比如, 要把二进制数1.01在不改变原值的情况下填满八位内存, 写出来就应该是: 1.010 0000, 即需要在低位补0。同理, 本例中因为尾数部分存储的实际上是省略了整数部分 1. 之后, 剩余的小数部分, 所以这里补0时也需要在低位补0:

原尾数是: 01001(不到23位)

补零之后是: 0100 1000 0000 0000 000 (补至23位)

实验

所以根据上述浮点数存储原理,我们可以自己实现浮点数取整的方法。

我们以float32型的数据10.5为例:

首先用math.Float32bits()方法获取10.5的二进制表示为:01000001001010000000000000000000

其中符号位为0;偏移后的指数位为10000010;尾数位为01010000000000000000000

想要获取浮点数的整数部分,首先要获取指数位,我们以0到31来表示二进制数下标,那么指数位为第23到30位,可以采用先左移1位,在右移24位的方式获取n := uint(b << 1 >> 24)

如果n<127,说明指数位为负数,整数部分为0。

然后再看尾数位,根据上述的描述,尾数位隐藏了高位的1,所以在获取完前n-127位尾数位后,在补充上高位的1,最后不要忘记符号位。

func ParseInt(f float32) int {b := math.Float32bits(f)n := uint(b << 1 >> 24)if n < 127 {fmt.Println("整数部分为0")return 0} else {x := b<<9>>(32+127-n) | (1 << (n - 127))if b&(1<<31) != 0 {return int(x) * -1}return int(x)}
}

同理,我们也可以自己判断浮点数是否为整数。

需要注意的是,go语言中float32的最小可以表示的浮点数数为2^-23≈0.0000001192,小于这个值就无法表示了,所以当输入为1.00000001时,返回值为true;所以当输入为1.0000001时,返回值为false

func IsInt(f float32) bool {b := math.Float32bits(f)n := uint(b << 1 >> 24)if n == 0 {return true}if n < 127 {return false} else {if uint(b<<(9+n-127)) > 0 {return false} else {return true}}
}

参考文献:(IEEE754详解(最详细简单有趣味的介绍)_明月几时有666的博客-CSDN博客_ieee754

go语言基础之浮点数相关推荐

  1. C语言基础:for循环演示源码,字符循环和浮点数循环

    把内容过程中重要的一些内容做个珍藏,下面的内容是关于C语言基础:for循环演示,字符循环和浮点数循环的内容. #include <stdio.h>int main (){char lett ...

  2. Go语言基础之数据类型

    Go语言基础之数据类型 Go语言中有丰富的数据类型,除了基本的整型.浮点型.布尔型.字符串外,还有数组.切片.结构体.函数.map.通道(channel)等.Go 语言的基本类型和其他语言大同小异. ...

  3. php flock 都是true_PHP从入门到精通(三)PHP语言基础

    PHP从入门到精通(三)PHP语言基础 一.PHP标记风格 PHP支持4种标记风格 1.XML风格.(推荐使用) <?phpecho "这是XML分割的标记"; ?> ...

  4. PHP学习笔记-PHP语言基础1

    转载请标明出处: http://blog.csdn.net/hai_qing_xu_kong/article/details/50951976 本文出自:[顾林海的博客] 前言 "合抱之木, ...

  5. Java核心技术笔记 语言基础

    <Java核心技术 卷Ⅰ> 第3章 Java 的基本程序设计结构 一些规则 类命名:CamelCase 驼峰命名法,以及必须是字母开头,后面跟字母和数字的任意组合: 源代码文件名:必须与公 ...

  6. Java程序员从笨鸟到菜鸟之(二十八)Javascript总结之语言基础

    JavaScript 脚本语言作为一门功能强大.使用范围较广的程序语言,其语言基础包括数据类型.变量.运算符.函数以及核心语句等内容.本篇文章主要介绍JavaScript 脚本语言的基础知识 一:基础 ...

  7. 黑马程序员C语言基础(第五天)运算符与表达式、程序流程结构、数组和字符串、函数

    https://www.bilibili.com/video/BV15W411K7k6?p=93&spm_id_from=pageDriver 黑马程序员C语言基础(第五天)运算符与表达式.程 ...

  8. c语言枚举变量自增报错,C_数据结构与算法(1):C语言基础

    C_数据结构与算法(一):C语言基础 致初学者的我:一切都是由浅入深. 每种语言都有每种语言的特性,基本的特性是相同的,下面依照惯例写hello world,相关编译后面再介绍. // C语言用&qu ...

  9. [GO语言基础] 三.变量声明、数据类型、标识符及编程练习12题

    作为网络安全初学者,会遇到采用Go语言开发的恶意样本.因此从今天开始从零讲解Golang编程语言,一方面是督促自己不断前行且学习新知识:另一方面是分享与读者,希望大家一起进步.前文介绍了Go的编译运行 ...

最新文章

  1. PHP JSON_ENCODE 不转义中文汉字的方法
  2. html5画布可以p图,HTML5图像适合发布在画布上
  3. jooq 分页排序_将jOOQ与Spring结合使用:排序和分页
  4. python中什么叫合法的标识_python合法标识符要求是什么
  5. php 商城套餐搭配功能,速卖通商品搭配套餐功能已上线!设置速卖通搭配套餐仅需三步...
  6. flutter -------- GridView的使用
  7. Winsock编程补遗
  8. crowd counting_[crowd_counting]-SFANet-arxiv1902
  9. Git(4)-- 如何退出 git log 和 git commit 状态
  10. 第九章-安装RPM包或源码包
  11. 计算机组成原理讲义 微盘,计算机组成原理课件.pdf
  12. java导出出行客人到Excel
  13. 计算机一直进入安全模式开机,电脑启动时自动进入安全模式怎么办
  14. 01Java方法重写与重载的区别
  15. perl 处理 回车 换行符
  16. 打开谷歌浏览器弹出hao123(俗称被绑架)(SB-hao123)
  17. 笔记——51控制DS18B20温度控制篇章2之读取温度值
  18. I need tests now!
  19. MacW最新资讯:macOS BigSur正式版来了!这些新变化和新功能值得一试
  20. NodeMCU文档中文翻译 7 DHT温湿度传感器模块

热门文章

  1. HDMI-USB视频采集卡使用教程
  2. WriteFile 错误(GetLastError)返回998
  3. uniapp如何给全端小程序添加激励广告详细教程
  4. Photozoom图像放大的技术一二事
  5. 7-10 高空坠球 (20 分) 皮球从某给定高度自由落下,触地后反弹到原高度的一半,再落下,再反弹,……,如此反复。问皮球在第n次落地时,在空中一共经过多少距离?第n次反弹的高度是多少?
  6. Oracle 9i与MS SQL Server 2000之比较连载五.zz
  7. Struts2漏洞 - Struts2-015 Struts2-016 Struts2-045
  8. Yoga是联想PC+战略的延伸和拓展
  9. fefefwefwefw
  10. python画直线--2点法