go语言基础之浮点数
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语言基础之浮点数相关推荐
- C语言基础:for循环演示源码,字符循环和浮点数循环
把内容过程中重要的一些内容做个珍藏,下面的内容是关于C语言基础:for循环演示,字符循环和浮点数循环的内容. #include <stdio.h>int main (){char lett ...
- Go语言基础之数据类型
Go语言基础之数据类型 Go语言中有丰富的数据类型,除了基本的整型.浮点型.布尔型.字符串外,还有数组.切片.结构体.函数.map.通道(channel)等.Go 语言的基本类型和其他语言大同小异. ...
- php flock 都是true_PHP从入门到精通(三)PHP语言基础
PHP从入门到精通(三)PHP语言基础 一.PHP标记风格 PHP支持4种标记风格 1.XML风格.(推荐使用) <?phpecho "这是XML分割的标记"; ?> ...
- PHP学习笔记-PHP语言基础1
转载请标明出处: http://blog.csdn.net/hai_qing_xu_kong/article/details/50951976 本文出自:[顾林海的博客] 前言 "合抱之木, ...
- Java核心技术笔记 语言基础
<Java核心技术 卷Ⅰ> 第3章 Java 的基本程序设计结构 一些规则 类命名:CamelCase 驼峰命名法,以及必须是字母开头,后面跟字母和数字的任意组合: 源代码文件名:必须与公 ...
- Java程序员从笨鸟到菜鸟之(二十八)Javascript总结之语言基础
JavaScript 脚本语言作为一门功能强大.使用范围较广的程序语言,其语言基础包括数据类型.变量.运算符.函数以及核心语句等内容.本篇文章主要介绍JavaScript 脚本语言的基础知识 一:基础 ...
- 黑马程序员C语言基础(第五天)运算符与表达式、程序流程结构、数组和字符串、函数
https://www.bilibili.com/video/BV15W411K7k6?p=93&spm_id_from=pageDriver 黑马程序员C语言基础(第五天)运算符与表达式.程 ...
- c语言枚举变量自增报错,C_数据结构与算法(1):C语言基础
C_数据结构与算法(一):C语言基础 致初学者的我:一切都是由浅入深. 每种语言都有每种语言的特性,基本的特性是相同的,下面依照惯例写hello world,相关编译后面再介绍. // C语言用&qu ...
- [GO语言基础] 三.变量声明、数据类型、标识符及编程练习12题
作为网络安全初学者,会遇到采用Go语言开发的恶意样本.因此从今天开始从零讲解Golang编程语言,一方面是督促自己不断前行且学习新知识:另一方面是分享与读者,希望大家一起进步.前文介绍了Go的编译运行 ...
最新文章
- PHP JSON_ENCODE 不转义中文汉字的方法
- html5画布可以p图,HTML5图像适合发布在画布上
- jooq 分页排序_将jOOQ与Spring结合使用:排序和分页
- python中什么叫合法的标识_python合法标识符要求是什么
- php 商城套餐搭配功能,速卖通商品搭配套餐功能已上线!设置速卖通搭配套餐仅需三步...
- flutter -------- GridView的使用
- Winsock编程补遗
- crowd counting_[crowd_counting]-SFANet-arxiv1902
- Git(4)-- 如何退出 git log 和 git commit 状态
- 第九章-安装RPM包或源码包
- 计算机组成原理讲义 微盘,计算机组成原理课件.pdf
- java导出出行客人到Excel
- 计算机一直进入安全模式开机,电脑启动时自动进入安全模式怎么办
- 01Java方法重写与重载的区别
- perl 处理 回车 换行符
- 打开谷歌浏览器弹出hao123(俗称被绑架)(SB-hao123)
- 笔记——51控制DS18B20温度控制篇章2之读取温度值
- I need tests now!
- MacW最新资讯:macOS BigSur正式版来了!这些新变化和新功能值得一试
- NodeMCU文档中文翻译 7 DHT温湿度传感器模块
热门文章
- HDMI-USB视频采集卡使用教程
- WriteFile 错误(GetLastError)返回998
- uniapp如何给全端小程序添加激励广告详细教程
- Photozoom图像放大的技术一二事
- 7-10 高空坠球 (20 分) 皮球从某给定高度自由落下,触地后反弹到原高度的一半,再落下,再反弹,……,如此反复。问皮球在第n次落地时,在空中一共经过多少距离?第n次反弹的高度是多少?
- Oracle 9i与MS SQL Server 2000之比较连载五.zz
- Struts2漏洞 - Struts2-015 Struts2-016 Struts2-045
- Yoga是联想PC+战略的延伸和拓展
- fefefwefwefw
- python画直线--2点法