精华内容
下载资源
问答
  • float与double精度丢失问题

    千次阅读 2018-05-14 14:27:17
    long price=new Double(a*100).longValue();结果是3.799999999.......大部分程序员都知道浮点类型能用来做精确表示和运算,对根本原因能随口说来的可能并多,借着这次机会,把涉及到计算机原理的知识点剖析下.....
    解决一个价格转换显示的bug
    double a=Double.parseDouble(3.80);
    long price=new Double(a*100).longValue();
    结果是3.799999999.......
    大部分程序员都知道浮点类型不能用来做精确表示和运算,对根本原因能随口说来的可能并不多,借着这次机会,把涉及到计算机原理的知识点剖析下。
    出现上述结果的根本原因是计算机使用二进制01无法准确表示某些带小数位的十进制数据
    十进制数据转换成二进制数据,需经过如下计算:
    1、整数部分
    用该整数连续除以2,取余数,商再除以2,直到商等于0为止,最后把得到的余数按相反的顺序排列,即“除2取余法”
    2、小数部分
    小数部分“乘2取整,顺序排列”法,小数部分乘以2,从乘积中取整数部分,剩余的小数部分乘以2,
    再把乘积的整部部分取出,剩余的小数部分乘以2,直到乘积中的小数部分为0或达到所要求的精度为止,把取出的整数部分顺序排列,即“乘2取整法”。
    3、相加
    最后把整数部分和小数部分相加,得到二进制数据
    例如:十进制的3.8转换成二进制数值,步骤如下:
    3(整数部分)
    3/2=1................1
    1/2=0.................1
    十进制3 转换为二进制 11
    0.8(小数部分)
    0.8*2=1.6................1
    0.6*2=1.2.................1
    0.2*2=0.4.................0
    0.4*2=0.8.................0
    0.8*2=1.6................1
    ....
    十进制0.8 转换为二进制 (0.11001100.....) 后边无限循环1100这段二进制数值,因此也就出现了上述的3.799999的情况。

    java 的浮点类型都依据 IEEE 754 标准。IEEE 754 定义了32 位和 64 位双精度两种浮点二进制小数标准。
    IEEE 754 用科学记数法以底数为 2 的小数来表示浮点数。32 位浮点数用 1 位表示数字的符号,用 8 位来表示指数,用 23位来表示尾数,即小数部分。作为有符号整数的指数可以有正负之分。小数部分用二进制(底数 2 )小数来表示。对于64位双精度浮点数,用 1 位表示数字的符号,用 11 位表示指数,52 位表示尾数。
    在 IEEE 754 的 double 没有办法表示出 0.8,只能得到一个近似值。
    float和double只能用来做科学计算或者是工程计算,在商业计算等精确计算中,用java.math.BigDecimal。
    BigDecimal的解决方案就是,不使用二进制,而是使用十进制(BigInteger)+小数点位置(scale)来表示小数。
    上述的39.8=398 * 0.1^1 这种表示方式下,避免了小数的出现,就不会有精度问题了。
    展开全文
  • 因此,在代码中存在,分转元,元转分的操作,但是这些操作涉及到float或double转成int或long;或者反向转换时会有精度丢失的问题。 具体是因为什么导致的精度丢失,这是跟数据保存以二进制存储引起的,这里追究...

    前言

    业务中有涉及到金额操作的,往往入库的时候在数据库以分为单位存储,但是涉及到具体的业务处理的,可能就要转换成元,有些显示之类的也要以元为单位显示。因此,在代码中存在,分转元,元转分的操作,但是这些操作涉及到float或double转成int或long;或者反向转换时会有精度丢失的问题。
    具体是因为什么导致的精度丢失,这是跟数据保存以二进制存储引起的,这里不追究原因,就看现象,以及如何规避这个问题。

    精度丢失现象举例

    简单的float转int,元转分,直接通过*100转换

    float fee = 2.09f;
     //元转分
     int feeYuan = Float.valueOf(fee * 100).intValue();
     System.out.println(fee *100);
     System.out.println(feeYuan);
    

    上述代码执行结果:
    直接转换结果
    可以看出,当float类型乘以100以后,精度就丢失了,不是等于209,而是一个约等于209的数,然后在这个基础上转换成int后就变成208了。

    规避方案(有坑的地方)

    总所周知,java中有BigDecimal可以操作该类转换数据,避免精度丢失问题;但是,这里举个例子,使用了BigDecimal但是精度还是有问题的现象:

    float fee = 2.09f;
     //元转分
       String fenToYuan = "100";
       int bFee = new BigDecimal(fee).multiply(new BigDecimal(fenToYuan)).intValue();
       System.out.println(new BigDecimal(fee));
       System.out.println(bFee);
    

    上述代码执行结果:
    在这里插入图片描述
    这里我们发现,我们使用了BigDecimal但是,元转分的时候还是丢失精度了,这里的问题是new BigDecimal时传入的对象是个float类型,当使用float类型创建对象时出来的对象精度就丢失了,而不是乘以100时丢失的。

    没问题的改造

    操作BigDecimal时,新建对象时最好还是以String对象比较好,不会出现问题。

    float fee = 2.09f;
     //元转分
      String fenToYuan = "100";
      int bFee = new BigDecimal(String.valueOf(fee)).multiply(new BigDecimal(fenToYuan)).intValue();
      System.out.println(new BigDecimal(String.valueOf(fee)));
      System.out.println(bFee);
    

    执行结果:
    在这里插入图片描述
    这样就没问题了。
    同理:如果要分转元的话:

    int fen = 309;
      String fenToYuan = "100";
      double yuan = new BigDecimal(String.valueOf(fen)).divide(new BigDecimal(fenToYuan), 2, RoundingMode.HALF_UP)
          .doubleValue();
    

    另一个方案

    这里还有一个其他方案处理分元转换,
    先把数字类型的值转换成String,然后通过移动"."的位置。
    下面举个分转元的例子,仅供参考:

    public static String changeFentoYuan(int fen)
        {
            String str = Math.abs(fen) + "";
            int len = str.length();
            
            String yuan;
            if (len == 1)
            {
                yuan = "0.0" + str;
            }
            else if (len == 2)
            {
                yuan = "0." + str;
            }
            else
            {
                yuan = str.substring(0, len - 2) + '.' + str.substring(len - 2);
            }
            
            return (fen < 0) ? ('-' + yuan) : yuan;
        }
    
    展开全文
  • 首先,JAVA的基本数据类型包括:byte、int、short、long、float、double、char、boolean。前七个数据类型所对应的字节大小分别为1、4、2、8、4、8、2。(先讨论boolean的大小,有争议。) int 和float都是4字节...

    List item

    JAVA中关于int、float的存储字节和精度的讨论

    **首先,JAVA的基本数据类型包括:byte、int、short、long、float、double、char、boolean。前七个数据类型所对应的字节大小分别为1、4、2、8、4、8、2。(先不讨论boolean的大小,有争议。)
    int 和float都是4字节。但因为所表示数据范围不同,其所存储的形式也不同。虽然都是32位,但int的32位数据的存储方式为:最高位符号位(1位),剩下31位表示数据大小。因此int的数据表示范围为-231——+231-1(具体表示范围的详解会在下方补充)。而float和double设计用来填充小数部分无法表示的空白。因此float的数据设计存储形式为最高位符号位(1位),再向后8位为阶码(也成移码),最后23位为尾数表示数据大小。float浮点表示小数采用类似科学计数法的形式。分为尾数(尾码)和指数(阶码)两个部分。所以float虽然看起来表示范围很大,但是有些数据缺失表示不到的。
    以8位十进制数为例,如果8位全部用来表示数据(即8位全为尾数),类似于int,和4位用于表示指数,4位用于表示数据大小(尾数),类似于float。当数据小于等于4位时,比如00001234,那么int转为float时不会出现精度丢失,因为float的尾数部分也可以准确表示数据大小。但是如果数据为12345678,那么从int转为float时,float就无法准确表示尾数的所有部分了,他只能舍弃后四位。

    展开全文
  • 数据类型 基本数据类型 基本数据类型 包装类 char Character ...double Double ...long Long ...小类型大类型: ... long long ->... double ...大类型小类型: 有可能造成数据精度丢失 double ->

    数据类型

    基本数据类型

    基本数据类型 包装类
    char Character
    int Integer
    float Float
    double Double
    boolean Boolean
    long Long
    short Short
    byte Byte

    自动类型转换

    小类型转大类型:

    int -> long
    long -> float
    float -> double
    

    强制类型转换

    大类型转小类型:

    有可能造成数据精度丢失

    double -> int
    

    引用数据类型

    除基本数据类型外的所有数据类型都是引用类型

    面向对象

    方法重载

    • 同一个类中
    • 方法名称相同
    • 返回值不同
    • 参数列表不同

    构造器

    • 创建对象时进行初始化
    • 系统默认提供无参构造器,一旦自定义了,系统将不再提供
    • 构造器可以被重载

    方法重写

    • 继承中发生
    • 子类重写父类方法
    • 方法名、参数列表、返回值均形同
    • 业务代码不同

    instanceof

    判断对象类型

    new Hello() instanceof Hello
    

    ==和equals方法

    • ==
      • 基本数据类型时判断两边的值
      • 引用数据类型时判断两边的引用
    • equals
      • 判断两边的引用

    Java集合

    • HashSet
      • 无序
      • 线程不安全
      • 值可以为null
      • 值不重复
    • LinkedHashSet
      • HashSet的子类
      • 有序
        • 按插入顺序有序
      • 基于链表实现
    展开全文
  • byte、short、int,他们三者在计算时会转换成int类型,如果把int值转换为float值,或者把long值转换为double值,需要强制转换,但可能丢失精度。以上实线为自动转换,虚线为可能会丢失精度丢失精度:float和...
  • java 中 整数默认为int 小数默认为double 当使用整数时,却想让它为int时,可以在...低级高级 自动 比如 3--3.0 就是int类型转换double类型 高级低级 强制 因为有精度丢失 需要明确告诉编译器需要精度 .
  • 类型转换

    2020-08-09 13:49:09
    数据类型从低到高 byte–>short–>char–>int–>long–>float–>double 自动类型转换 数据类型低的可以直接转换数据类型高的 ...数据类型高的转换成数据类型低的 ...精度丢失就是浮
  • 有些会不丢失精度转换,而有些会丢失精度。 1.如果两个操作数中有一个是double类型,另一个操作数就会转换为double类型 2.否则,如果其中一个操作数是float类型,另一个操作数就会转换为float类型 3. 否则,如果...
  • Java入门(类型转换)

    2020-09-01 19:53:14
    这也是因为低位数(即低精度)的数据类型转换为高数位(即高密度)的数据类型存在精度丢失和数据丢失的情况 1、转换顺序: byte → short short → int char → int int → long long → float float → double ...
  • 类型转换 ...高精度转换为低精度需要进行强制类型转换(但是会出现精度丢失) 3.低精度转换为高精度可以自动进行转换(但是可能会出现内存溢出的问题) 4.能把数字类型转换为相干的类型 ...
  • 建议,丢失精度 范围: byte,char,short &lt; int &lt; long &lt; float &lt; double 整数使用 int 小数使用 double 了解ASCII编码表 理解int类型和char类型的运算原理 (掌...
  • java运算符与自动类型转换

    千次阅读 2017-07-09 10:54:16
    1)精度小的向精度大的转换(精度丢失) 2)字节短的向字节长的转换 3)char和int可以互换,char是用ASCII码表示 byte->(int=char)->long->float->double 示例代码1 int a =5; System.out.println("value i
  • 基本数据类型转换

    2019-05-28 00:09:53
    自动类型转换 容量小的类型自动转换成容量大的数据类型;... 精确值近似值需要强制转换,但是可能丢失精度。 例如:byte a=10;short b=a; 2.强制类型转换 容量大的类型自动转换成容量小的...
  • c# 数据类型转换

    2017-02-27 11:37:00
    byte, short, int, long, fload, double等根据其顺序向后可以隐式自动完成类型的转换,隐式转移的前提是目标类型精度高于源类型,如:short隐式转换为int,因其int精度高于short,所以隐式完成转换后,其数据不丢失。...
  • 自动类型转换和强制类型转换 标签(空格分隔): C 双学位高级语言程序设计 C算术运算和表达式 C语言中经常遇到不同数据类型在同一运算中转化的情况,这遵循...虽然自动类型转换使数据精度不容易丢失,但是他的自动
  • java基本数据类型的转换 ...注意:强制转换可能会有数据溢出(右侧数值大小能超过左侧类型范围)或者精度丢失(浮点数整形) byte short char 进行数据转换时,JVM首先会自动转为int类型,然后进行数据运
  • 实线表示无数据丢失自动转换类型,而虚线表示在转换时可能会有精度损失 可以将整型常量直接赋值给byte、short、char等类型变量,而需要进行强制转换,只需超出 其表数范围即可 强制类型转换 强制类型转换,又...
  • 即逆向过程,可能丢失精度 int a=(int)3.1478932; 3、String不是基本数据类型—》final 强制转换—》包装类 String a = "73874.48787548"; double b = Double.parseDouble(a); System.out.println(b);
  • 语法:(要转换成为的数据类型)变量 强转有可能溢出或丢失精度 2)两点规则: 2.1)整数直接量可以直接赋值给byte,short,char,但能超出范围 2.2)byte,short,char型数据参与运算时,系统会自动将其先转换为int再运算...
  • 数据类型转换:当把一种数据类型的值赋给另一个数据类型的变量时需要进行...范围小→大:byte、char、 short→int→long→float→double boolean类型能与其它数据类型运算 byte,short,char之间不会相互转换,他们三者
  • 类型转换6条规则 基本数据类型中除了Boolean类型外,剩余7种类型...当取值范围大的类型能直接给取值范围小的类型赋值,则必须进行强制类型转换也叫做显式类型转换,但是可能会存在精度丢失。 当对byte short char ...
  • 2021-06-08类型转换

    2021-06-08 21:14:30
    能对布朗值进行转换 精度问题 System.out.println(6789.98); System.out.println((int)6789.98);//0.98会丢失 低------------------------------>高 byte,short,char->int->long->float->...
  • 1、基本数据类型中除了Boolean类型以外,剩余7种类型可以进行相互转换 ...3、当取值范围大的类型能直接给范围小的类型赋值,则必须进行强制类型也叫做显式类型转换,但是可能会存在精度丢失 4、当对byte short c...
  • 水题,但是pow的精度不高,应该是转换成long long精度丢失了干脆直接double就可以了。被hack掉了。用long long能存的下 #include <bits/stdc++.h> using namespace std; typedef long long ll; const...
  • 11.15 在控制台输出使用Scanner会比较慢,可以使用System.in.read(),再添加到数组里 11.16 1、为什么float,long定义的变量需要加f... 应为整数默认是int类型,向下转换丢失精度,向上装换回丢失精度 ,而  s
  • Java学习笔记2

    千次阅读 2021-03-11 10:47:36
    虚线代表可以直接转换但可能会丢失一定的精度,如long类型转换为double类型时会丢失一定精度。 特例:可以将整型常量直接赋值给byte、short、 char等类型变量,而需要进行强制类型转换,只要超出其表数范围即可...
  • 温故知新

    2016-08-07 20:15:50
    java的数据类型 基本数据类型 定义 整型 byte ...在jdk1.5之前 Integer 和 int 转换还需要调用方法,能自动转换 ...低精度向高精度转换没问题,但是高精度向低精度转换会造成精度丢失,也叫溢出 L
  • 【Java】关于强制类型转换

    千次阅读 2014-01-13 11:03:11
    Java支持基本数据类型间的转换,参看下图 ...Java支持byte,short,int,long,float,double之间的自动转换,但要遵循一条规则,就是只有低精度类型可以向高精度类型,反之可以。也就是byte byte by=1

空空如也

空空如也

1 2 3
收藏数 41
精华内容 16
关键字:

double转long不丢失精度