如何正确使用float和double?

qchen 等级 268 0 0
标签: 浮点数

1、典型问题

问题一:条件判断超预期

System.out.println(1f == 0.9999999f)    // false
System.out.println(1f == 0.99999999f)   // true

问题二:数据转换超预期

float f = 1.1f;
double d = (double)f;
System.out.println(f);  // 1.1
System.out.println(d);  // 1.100000023841858

问题三:基本运算超预期

System.out.println( 0.2 + 0.7 ); // 0.8999999999999999 

问题四:数据自增超预期

float f1 = 8455263f;  // 7位数
for (int i = 0; i < 10; i++) {
    System.out.println(f1);
    f1++;
}
// 打印:8455263.0
// 打印:8455264.0
// 打印:8455265.0
// 打印:8455266.0
// 打印:8455267.0
// 打印:8455268.0
// 打印:8455269.0
// 打印:8455270.0
// 打印:8455271.0
// 打印:8455272.0

float f2 = 84552631f;  // 8位数
for (int i = 0; i < 10; i++) {
    System.out.println(f2);
    f2++;
}
//    打印:8.4552632E7
//    打印:8.4552632E7
//    打印:8.4552632E7  
//    打印:8.4552632E7 
//    打印:8.4552632E7
//    打印:8.4552632E7
//    打印:8.4552632E7
//    打印:8.4552632E7
//    打印:8.4552632E7
//    打印:8.4552632E7

2、浮点数的精度问题

浮点数在计算机中的存储方式遵循IEEE 754 浮点数计数标准,可以用科学计数法表示为: 如何正确使用float和double? 对于float和double两种浮点数在内存中的存储结构如下图所示: 如何正确使用float和double? 如何正确使用float和double? 1、符号部分(S)

  • 0-正
  • 1-负

2、阶码部分(E)(指数部分)

  • 对于float型浮点数,指数部分8位,考虑可正可负,因此可以表示的指数范围为-127 ~ 128
  • 对于double型浮点数,指数部分11位,考虑可正可负,因此可以表示的指数范围为-1023 ~ 1024

3、尾数部分(M) 浮点数的精度是由尾数的位数来决定的:

  • 对于float型浮点数,尾数部分23位,换算成十进制就是 2^23=8388608,所以十进制精度只有6 ~ 7位;
  • 对于double型浮点数,尾数部分52位,换算成十进制就是 2^52 = 4503599627370496,所以十进制精度只有15 ~ 16位

所以,上述0.99999999f超出float型浮点数据的精度范围。

3、如何解决精度问题

  • 用字符串或者数组解决多位数问题
  • Java的大数类:BigDecimal、BigInteger
    BigDecimal num3 = new BigDecimal( Double.toString( 1.0f ) );
    BigDecimal num4 = new BigDecimal( Double.toString( 0.99999999f ) );
    System.out.println( num3 == num4 );  // 打印 false
    

BigDecimal num1 = new BigDecimal( Double.toString( 0.2 ) ); BigDecimal num2 = new BigDecimal( Double.toString( 0.7 ) );

// 加 System.out.println( num1.add( num2 ) ); // 打印:0.9

// 减 System.out.println( num2.subtract( num1 ) ); // 打印:0.5

// 乘 System.out.println( num1.multiply( num2 ) ); // 打印:0.14

// 除 System.out.println( num2.divide( num1 ) ); // 打印:3.5

局限性:大数类的运算效率肯定是不如原生类型效率高,代价还是比较昂贵的,是否选用需要根据实际场景来评估。
收藏
评论区

相关推荐

初级Java开发工程师!绝密文档,面试手册全面突击!!!秋招已经到来
这里我要明说一下,不是Java初级和学习Java的千万不要乱看,否则你会怀疑人生,因为会浪费你时间啊!!!本次考点是Java初级开发工程师面试必备的一些东西!!! 1、数据类型 基本类型cbyte/8、short/16、int/32、long/64、boolean/ 、char/16、float/32、double/64boolean只有两个值,true、f
C++中内置变量的初始化
对于全局的变量 ------- 如果内置类型的变量未被显示地初始化,它的值将由定义的位置决定。 (1).定义在函数体之外的变量将被初始化为0; (2).定义在函数体内部的变量将不被初始化,它的值将是任意的。 对于(1)举例如下: short sn; int in; long ln; long long lln;
C++异常的几种捕获方式
#### 捕获指定的类型 这样的话可以对每种异常做出不同的处理,例如: #include <iostream> using namespace std; void A(int n){ int a = 1; float b = 0.2; double c = 0.3;
C++类型转换
### 隐式转换 在赋值给一个兼容类型会出现隐式类型转换.比如下面这个例子. short a=2000; int b; b=a; 在以上例子中.值从short自动提升到int,这是标准转换。标准转换影响基本数据类型,它在类型数字类型之间(`short` to `int`, `int` to `float`, `double` t
C语言 函数
**1.返回值类型** 51.有一个函数原型如下所示,则该函数的返回类型为( ) 。 C abc(float x,float y); A. void B. double C. int D. float 3 1 51.有一个函数原型如下所示,则该函数的返回类型为( )
MongoDB 数据类型
### 一.MongoDB 之 数据类型 Object  ID :Documents 自动生成的 \_id,插入数据时候会生成 \_id,唯一字段 String: 字符串,必须是utf-8 Boolean:布尔值,true 或者false Integer:整数 (Int32 Int64 你们就知道有个Int就行了,一般我们用Int32) Doub
JAVA基本类型和引用类型
**一、基本数据类型** ------------ java中一共分为8种基本数据类型:byte、short、int、long、float、double、char、boolean,其中byte、short、int、long是整型。float、double是浮点型,char是字符型,boolean是布尔型。 **二、引用类型** ---------- j
JDBC Types与Java Types的映射关系
JDBC Type Java Type CHAR String VARCHAR String LONGVARCHAR String NUMERIC java.math.BigDecimal DECIMAL java.math.BigDecimal BIT boolean BOOLEAN boolean TINYINT byt
JNI学习笔记
    Java类型                  本地类型                   JNI中定义的别名      int long jint long \_int64 jlong byte signed char jbyte boolean unsigned char jboolean char unsign
Java面试官:double精度真的比float低吗?
![](https://oscimg.oschina.net/oscnet/f9a92f58-a1be-4de7-9d67-58d1554842b4.png) 我有一个朋友,叫老刘,戴着度数比我还高的近视镜,显得格外的“程序员”;穿着也非常“不拘一格”,上半身是衬衣西服,下半身是牛仔裤运动鞋。 我和老刘的感情非常好,每周末我们都要在一起吃顿饭。这周,
java 知识点 小结
1. Java 8种基本类型:byte  char  short int  long  double  float  boolean * Byte:8位 * Short : 16位 * Int: 32位 * Long: 64位 * Float: 32位 * Double: 64位 2. List set map List:有序;
MySQL的一些小问题
在建表的时候,总有一些模糊的点让我不得不百度: **1、金钱字段存储应当选择float、decimal、double?** 应当选择decimal。 他是以字符串形式存储的,不会损失精度,为啥浮点型的(单精度、双精度)会损失精度呢,看下面的例子: 定点数如果不写精度和标度,则按照默认值decimal(10,0) 来操作,也就是存储11.1时候,会自
Android实现简单的检测手机自由落体关闭屏幕
实现功能如下:在背景运行app,检测到自由落体状态时,熄灭屏幕,可重复测试。 1\. 检测自由落体动作 需要使用到加速度感应器 TYPE\_ACCELEROMETER SensorManager mSensorManager; private float mLastX; private float mLastY; pr
Mongodb之数据类型
一.MongoDB的数据类型 -------------- Object  ID :Documents 自生成的 \_id String: 字符串,必须是utf-8 Boolean:布尔值,true 或者false (Python中 True False 首字母大写) Integer:整数 (Int32 Int64 你们就知道有个Int就行了,一般我
如何正确使用float和double?
1、典型问题问题一:条件判断超预期javaSystem.out.println(1f 0.9999999f) // falseSystem.out.println(1f 0.99999999f) // true问题二:数据转换超预期javafloat f 1.1f;double d (double)f;System.out.println(

热门文章

Java中6种创建对象的方式枚举Enum的使用Java8函数式编程

最新文章

Java8函数式编程Java中6种创建对象的方式枚举Enum的使用