我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java学习笔记:关于Java double类型相加问题

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java学习笔记:关于Java double类型相加问题

Java double类型相加问题

多个double类型的数直接相加的时候,可能存在精度误差.( 由于计算机算法以及硬件环境决定只能识别 0 1。计算机默认的计算结果在都在一个指定精度范围之内,想往深的了解,可以学习数值分析等)

在金融方面是绝对不允许的,好在java开发者有这个先见之明。

java.math.*里面提供了BigDecimal类(提供高精度计算的方法)

一、这个时候就要采用BigDecimal函数进行运算

第一步、建立String类型的数据

第二步、创建BigDecimal对象BigDecimal(Double.toString(double))

以下两种不推荐:

BigDecimal(double)或者BigDecimal(Double.valueOf(double)))

建议: 涉及到精度问题的时候,整个计算过程都是用String类型或者BigDecimal类对象。最后结果根据需求 在转过来。

另外该文章提供了一个计算辅助类Java Double相加出现的怪事

急需的话,直接学习、创建该工具类,就可以完成项目了。以下是 加法算法的几个实现的方法。


new BigDecimal(Double.toString(double)).add(new BigDecimal(Double.toString(double));

    
    public BigDecimal add(BigDecimal b1, double v2) {
        // BigDecimal b1=new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2);
    }


    
    public BigDecimal add(double v1, double v2) {
         BigDecimal b1=new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2);
    }

    
    public double add(double v1, double v2) {
         BigDecimal b1=new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2).doubleValue();
    }

二、double 三种加法比较

+,strictfp,BigDecimel

Strictfp —— Java 关键字。

可应用于类、接口或方法。

使用 strictfp 关键字声明一个方法时,该方法中所有的float和double表达式都严格遵守FP-strict的限制,符合IEEE-754规范。

严格约束意味着所有表达式的结果都必须是 IEEE 754 算法对操作数预期的结果,以单精度和双精度格式表示。


public class MathDemo {

    
    public static void main(String[] args) {
        System.err.println("普通 "+ addNormal(12353.21,21334.24,154435.03));
        System.err.println("strictfp "+addDouble(12353.21,21334.24,154435.03));
        System.err.println("BigDEcimel: "+add(12353.21,21334.24,154435.03));

    }

    public static double addNormal(double... v1) {
        double res = 0;
        for (int i = 0; i < v1.length; i++) {
            res += v1[i];
        }
        return res;
    }

    public static strictfp double addDouble(double... v) {
        double res = 0;
        for (int i = 0; i < v.length; i++) {
            res += v[i];
        }
        return res;
    }

    
    public static double add(double... v) {
        BigDecimal b  = new BigDecimal(Double.toString(v[0]));
        for (int i = 1; i < v.length; i++) {
            BigDecimal b2 = new BigDecimal(Double.toString(v[i]));
            b=b.add(b2);
        }
        return b.doubleValue();
    }
}

输入
12353.21,21334.24,154435.03三个类型的数据时候
结果:
普通 188122.47999999998
strictfp 188122.47999999998
BigDEcimel: 188122.48

输入
3.21, 4.24,5.03
结果
普通 12.48
strictfp 12.48
BigDEcimel: 12.48

输入:
12353.21,21334.24
结果:
普通 33687.45
strictfp 33687.45
BigDEcimel: 33687.45

结论是:

BigDecimal的算法精度比较好。 其余两种方法 都存在缺点。至于strictfp 这个关键字 是去平台化影响。比如32为机器和64位机器结果都一样。 对于精度计算结果影响不大。

附录:.


//使用double类型创建BigDecimal
  public BigDecimal(double val) {
        if (Double.isInfinite(val) || Double.isNaN(val))
            throw new NumberFormatException("Infinite or NaN");

        // Translate the double into sign, exponent and significand, according
        // to the formulae in JLS, Section 20.10.22.
        long valBits = Double.doubleToLongBits(val);
        int sign = ((valBits >> 63)==0 ? 1 : -1);
        int exponent = (int) ((valBits >> 52) & 0x7ffL);
        long significand = (exponent==0 ? (valBits & ((1L<<52) - 1)) << 1
                            : (valBits & ((1L<<52) - 1)) | (1L<<52));
        exponent -= 1075;
        // At this point, val == sign * significand * 2**exponent.

        
        if (significand == 0) {
            intVal = BigInteger.ZERO;
            intCompact = 0;
            precision = 1;
            return;
        }

        // Normalize
        while((significand & 1) == 0) {    //  i.e., significand is even
            significand >>= 1;
            exponent++;
        }

        // Calculate intVal and scale
        long s = sign * significand;
        BigInteger b;
        if (exponent < 0) {
            b = BigInteger.valueOf(5).pow(-exponent).multiply(s);
            scale = -exponent;
        } else if (exponent > 0) {
            b = BigInteger.valueOf(2).pow(exponent).multiply(s);
        } else {
            b = BigInteger.valueOf(s);
        }
        intCompact = compactValFor(b);
        intVal = (intCompact != INFLATED) ? null : b;
    }

Java double类详解

Double 类的构造方法

Double 类中的构造方法有如下两个。

  • Double(double value):构造一个新分配的 Double 对象,它表示转换为 double 类型的参数。
  • Double(String s):构造一个新分配的 Double 对象,它表示 String 参数所指示的 double 值。

分别使用以上两个构造方法获取 Double 对象:


Double double1 = new Double(5.556);    // 以 double 类型的变量作为参数创建 Double 对象
Double double2 = new Double("5.486");       // 以 String 类型的变量作为参数创建 Double 对象

Double 类的常用方法

在这里插入图片描述

如何将字符串 56.7809 转换为 double 类型的数值,或者将 double 类型的数值 56.7809 转换为对应的字符串呢?


String str = "56.7809";
double num = Double.parseDouble(str);    // 将字符串转换为 double 类型的数值
double d = 56.7809;
String s = Double.toString(d);    // 将double类型的数值转换为字符串

在将字符串转换为 double 类型的数值的过程中,如果字符串中包含非数值类型的字符,则程序执行将出现异常。

Double 类的常用常量

在 Double 类中包含了很多常量,其中较为常用的常量如下。

  • MAX_VALUE:值为 1.8E308 的常量,它表示 double 类型的最大正有限值的常量。
  • MIN_VALUE:值为 4.9E-324 的常量,它表示 double 类型数据能够保持的最小正非零值的常量。
  • NaN:保存 double 类型的非数字值的常量。
  • NEGATIVE_INFINITY:保持 double 类型的负无穷大的常量。
  • POSITIVE_INFINITY:保持 double 类型的正无穷大的常量。
  • SIZE:用秦以二进制补码形式表示 double 值的比特位数。
  • TYPE:表示基本类型 double 的 Class 实例。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java学习笔记:关于Java double类型相加问题

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java double类型相加问题举例分析

本篇内容介绍了“Java double类型相加问题举例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Java double类型相加问题多
2023-06-22

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录