java精度,java精度丢失问题

本文目录一览:

java 浮点数为什么精度会丢失

并不是java的浮点数精度会丢失,而是所有用二进制存储中的浮点数都可能会精度丢失(部分特殊的小数数值可以精确表示),所以计算机中存储的浮点数都存在精度丢失的风险,不过一边这个丢失的精度对我们正常的使用不会构成影响。

小数在转换为二进制时并不一定能用一个精确的二进制表示,大多数时候都是取的一个近似值,这就造成了精度的丢失。如果再用这个二进制进行计算,明显计算结果的精度会进一步丢失。

举个简单的例子把0.1用二进制表示(小数与二进制转换方法)

(1) 0.1 x 2 = 0.2  取整数位 0 得 0.0

(2) 0.2 x 2 = 0.4  取整数位 0 得 0.00

(3) 0.4 x 2 = 0.8  取整数位 0 得 0.000

(4) 0.8 x 2 = 1.6  取整数位 1 得 0.0001

(5) 0.6 x 2 = 0.2  取整数位 1 得 0.00011

(6) 0.2 x 2 = 0.4  取整数位 0 得 0.000110

(7) 0.4 x 2 = 0.8  取整数位 0 得 0.0001100

(8) 0.8 x 2 = 1.6  取整数位 1 得 0.00011001

(9) 0.6 x 2 = 1.2  取整数位 1 得 0.000110011

(n) …

得到一个无限循环的二进制小数 0.000110011…,没办法用一个精确的二进制表示0.1。而且计算机中存储一个浮点数所用的位数也是有限的,所以只能选择在某一个精度进行保存。

当然也有特殊的小数,比如0.25的二进制为0.01

附:代码之谜(五)- 浮点数(谁偷了你的精度?)

关于java单精度与双精度的问题

单精度和双精度的区别就是,双精度要比单精度所存储的位数要多,至于说3.14师双精度,是因为Java中,默认的小数都是double类型,也就算双精度的,如果要定义单精度的话,那就要在小数的后面加上一个f或者F,即 double d = 3.14; float f = 3.14f; 一定要注意后面有没有“f”和“F”啊,这个初学的时候,经常会考到。楼上说的,是对,但是,他那样写,就一定会报错。记住,单精度的变量定义,一定要在值的后面加上标识。

Java语言中的浮点型数据的float和double的单精度和双精度到底是啥意思?

主要有下面几个区别,手册上的,希望能帮到你

1、变量类型不同

float属于单精度型浮点数据。

double属于双精度型浮点数据。

2、指数范围不同

float的指数范围为-127~128。

double而double的指数范围为-1023~1024

3、表达式指数位不同

float的表达式为1bit(符号位)+8bits(指数位)+23bits(尾数位)

double的表达式为1bit(符号位)+ 11bits(指数位)+ 52bits(尾数位)

4、占用内存空间不同

float占4个字节(32位)内存空间,其数值范围为3.4E-38~3.4E+38。

double占8 个字节(64位)内存空间,其数值范围为1.7E-308~1.7E+308。

5、有效位数不同

float只能提供七位有效数字。

double可提供16位有效数字。

怎么控制精度在java

JAVA中如何对double或者float的浮点数进行精度计算,在JAVA中提供了多种参数来实现精度的不同控制方式。具体例子如下: 

转自

Java代码 

/* 

 * Created on 2005-6-5 

 * Author stephen 

 * Email zhoujianqiang AT gmail DOT com 

 * CopyRight(C)2005-2008 , All rights reserved. 

 */  

package com.soft4j.utility;  

  

import java.math.BigDecimal;  

  

/** 

 * 与小数位精度(四舍五入等)相关的一些常用工具方法. 

 *  

 * float/double的精度取值方式分为以下几种: br 

 * java.math.BigDecimal.ROUND_UP br 

 * java.math.BigDecimal.ROUND_DOWN br 

 * java.math.BigDecimal.ROUND_CEILING br 

 * java.math.BigDecimal.ROUND_FLOOR br 

 * java.math.BigDecimal.ROUND_HALF_UPbr 

 * java.math.BigDecimal.ROUND_HALF_DOWN br 

 * java.math.BigDecimal.ROUND_HALF_EVEN br 

 *  

 * @author stephen 

 * @version 1.0.0 

 */  

public final class RoundTool {  

  

    /** 

     * 对double数据进行取精度. 

     * p 

     * For example: br 

     * double value = 100.345678; br 

     * double ret = round(value,4,BigDecimal.ROUND_HALF_UP); br 

     * ret为100.3457 br 

     *  

     * @param value 

     *            double数据. 

     * @param scale 

     *            精度位数(保留的小数位数). 

     * @param roundingMode 

     *            精度取值方式. 

     * @return 精度计算后的数据. 

     */  

    public static double round(double value, int scale, int roundingMode) {  

        BigDecimal bd = new BigDecimal(value);  

        bd = bd.setScale(scale, roundingMode);  

        double d = bd.doubleValue();  

        bd = null;  

        return d;  

    }  

  

    /** 

     * 测试用的main方法. 

     *  

     * @param argc 

     *            运行参数. 

     */  

    public static void main(String[] argc) {  

        //下面都以保留2位小数为例  

          

        //ROUND_UP  

        //只要第2位后面存在大于0的小数,则第2位就+1  

        System.out.println(round(12.3401,2,BigDecimal.ROUND_UP));//12.35  

        System.out.println(round(-12.3401,2,BigDecimal.ROUND_UP));//-12.35  

        //ROUND_DOWN  

        //与ROUND_UP相反  

        //直接舍弃第2位后面的所有小数  

        System.out.println(round(12.349,2,BigDecimal.ROUND_DOWN));//12.34  

        System.out.println(round(-12.349,2,BigDecimal.ROUND_DOWN));//-12.34  

        //ROUND_CEILING  

        //如果数字0 则和ROUND_UP作用一样  

        //如果数字0 则和ROUND_DOWN作用一样  

        System.out.println(round(12.3401,2,BigDecimal.ROUND_CEILING));//12.35  

        System.out.println(round(-12.349,2,BigDecimal.ROUND_CEILING));//-12.34  

        //ROUND_FLOOR  

        //如果数字0 则和ROUND_DOWN作用一样  

        //如果数字0 则和ROUND_UP作用一样  

        System.out.println(round(12.349,2,BigDecimal.ROUND_FLOOR));//12.34  

        System.out.println(round(-12.3401,2,BigDecimal.ROUND_FLOOR));//-12.35  

        //ROUND_HALF_UP [这种方法最常用]  

        //如果第3位数字=5,则第2位数字+1  

        //备注:只看第3位数字的值,不会考虑第3位之后的小数的  

        System.out.println(round(12.345,2,BigDecimal.ROUND_HALF_UP));//12.35  

        System.out.println(round(12.3449,2,BigDecimal.ROUND_HALF_UP));//12.34  

        System.out.println(round(-12.345,2,BigDecimal.ROUND_HALF_UP));//-12.35  

        System.out.println(round(-12.3449,2,BigDecimal.ROUND_HALF_UP));//-12.34  

        //ROUND_HALF_DOWN  

        //如果第3位数字=5,则做ROUND_UP  

        //如果第3位数字5,则做ROUND_DOWN  

        System.out.println(round(12.345,2,BigDecimal.ROUND_HALF_DOWN));//12.35  

        System.out.println(round(12.3449,2,BigDecimal.ROUND_HALF_DOWN));//12.34  

        System.out.println(round(-12.345,2,BigDecimal.ROUND_HALF_DOWN));//-12.35  

        System.out.println(round(-12.3449,2,BigDecimal.ROUND_HALF_DOWN));//-12.34  

        //ROUND_HALF_EVEN  

        //如果第3位是偶数,则做ROUND_HALF_DOWN  

        //如果第3位是奇数,则做ROUND_HALF_UP  

        System.out.println(round(12.346,2,BigDecimal.ROUND_HALF_EVEN));//12.35  

        System.out.println(round(12.345,2,BigDecimal.ROUND_HALF_EVEN));//12.35  

    }  

}

 如果要求精确控制位数,推荐使用BigDecimal,这是在JDK1.4版本之后推荐的一个处理精度的类。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/286043.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-22 16:07
下一篇 2024-12-22 16:07

相关推荐

  • java client.getacsresponse 编译报错解决方法

    java client.getacsresponse 编译报错是Java编程过程中常见的错误,常见的原因是代码的语法错误、类库依赖问题和编译环境的配置问题。下面将从多个方面进行分析…

    编程 2025-04-29
  • Java JsonPath 效率优化指南

    本篇文章将深入探讨Java JsonPath的效率问题,并提供一些优化方案。 一、JsonPath 简介 JsonPath是一个可用于从JSON数据中获取信息的库。它提供了一种DS…

    编程 2025-04-29
  • Python官网中文版:解决你的编程问题

    Python是一种高级编程语言,它可以用于Web开发、科学计算、人工智能等领域。Python官网中文版提供了全面的资源和教程,可以帮助你入门学习和进一步提高编程技能。 一、Pyth…

    编程 2025-04-29
  • Java Bean加载过程

    Java Bean加载过程涉及到类加载器、反射机制和Java虚拟机的执行过程。在本文中,将从这三个方面详细阐述Java Bean加载的过程。 一、类加载器 类加载器是Java虚拟机…

    编程 2025-04-29
  • Java腾讯云音视频对接

    本文旨在从多个方面详细阐述Java腾讯云音视频对接,提供完整的代码示例。 一、腾讯云音视频介绍 腾讯云音视频服务(Cloud Tencent Real-Time Communica…

    编程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介绍

    本文将详细介绍Java Milvus SearchParam withoutFields的相关知识和用法。 一、什么是Java Milvus SearchParam without…

    编程 2025-04-29
  • 如何解决WPS保存提示会导致宏不可用的问题

    如果您使用过WPS,可能会碰到在保存的时候提示“文件中含有宏,保存将导致宏不可用”的问题。这个问题是因为WPS在默认情况下不允许保存带有宏的文件,为了解决这个问题,本篇文章将从多个…

    编程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java语言中的一个版本,于2014年3月18日发布。本文将从多个方面对Java 8中某一周的周一进行详细的阐述。 一、数组处理 Java 8新特性之一是Stream…

    编程 2025-04-29
  • Java判断字符串是否存在多个

    本文将从以下几个方面详细阐述如何使用Java判断一个字符串中是否存在多个指定字符: 一、字符串遍历 字符串是Java编程中非常重要的一种数据类型。要判断字符串中是否存在多个指定字符…

    编程 2025-04-29
  • VSCode为什么无法运行Java

    解答:VSCode无法运行Java是因为默认情况下,VSCode并没有集成Java运行环境,需要手动添加Java运行环境或安装相关插件才能实现Java代码的编写、调试和运行。 一、…

    编程 2025-04-29

发表回复

登录后才能评论