扫码关注官方订阅号
小伙看你根骨奇佳,潜力无限,来学PHP伐。
接@justjavac大神的答案
有个问题,String s = "0.12"; 调用Float.parseFloat(s);返回的结果偶尔会是0.1199 按道理0.12float类型完全可以表示的啊
这道理从何而来?凭空想象的吧 计算机存储任何数字都是基于二进制,那么浮点数怎么存储成二进制?这里Java遵循了IEEE754标准,大致过程如下
道理
二进制
IEEE754
整数部分除2取余
小数部分乘2取整
0.12 => 0.00011110101110000101000111101... // 发现了么? 十进制的有穷小数,在二进制中,变成了无穷 // 只有 小数部分 * 2^n == 1 的情况,用二进制表示才是有穷的
0.00011110101110000101000111101... => 1.1110101110000101000111101... * 2 ^ -4
1 8位 23位 存不下了 0 01111011 11101011100001010001111 (01...) + 2的-4次幂 除去整数部分1之后剩余的尾数 0舍1入后忽略这部分,精度就这样没了
1 . 1 1 1 0 . ... . 1 (?...) 1 * 2^0 + 1 * 2^-1 + 1 * 2^-2 + 1 * 2^-3 + 0 * 2^-1 + ... + 1 * 2^-23 + ???
鱼与熊掌不可兼得。
为什么设计 float 类型呢:
还有一个原因,比如:根号2,不管用什么类型,都没法精确标示出来。
float 用 4 个字节存储,double 用 8 个字节存储,精度肯定是有限的,但是一般的计算都足够了,用 float 和 double 计算比 BigDecimal 快得多。
float
double
BigDecimal
但是难免会遇到一些需要使用高精度的浮点运算,那就用 BigDecimal 了哇。作为显示输出,当然转换成字符串是必然的。但是如果需要将 BigDecimal 的结果用于其它接口,而接口只允许使用 float 或 double,那没办法,只能损失精度了。
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
接@justjavac大神的答案
这
道理从何而来?凭空想象的吧计算机存储任何数字都是基于
二进制,那么浮点数怎么存储成二进制?这里Java遵循了IEEE754标准,大致过程如下十进制数字转化成二进制表示形式,通过将
整数部分除2取余、小数部分乘2取整来完成转换转换成科学计数法(二进制下),将小数点移动到第一个1的右边
结果显而易见了,转换成IEEE754形式
当你再从2进制转换回10进制时,失去的部分就回不来了
鱼与熊掌不可兼得。
为什么设计 float 类型呢:
还有一个原因,比如:根号2,不管用什么类型,都没法精确标示出来。
float用 4 个字节存储,double用 8 个字节存储,精度肯定是有限的,但是一般的计算都足够了,用float和double计算比BigDecimal快得多。但是难免会遇到一些需要使用高精度的浮点运算,那就用
BigDecimal了哇。作为显示输出,当然转换成字符串是必然的。但是如果需要将BigDecimal的结果用于其它接口,而接口只允许使用float或double,那没办法,只能损失精度了。