在Java中保持双精度 [英] Retain precision with double in Java

查看:145
本文介绍了在Java中保持双精度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

公共类doublePrecision {
public static void main(String [] args){

double total = 0;
total + = 5.6;
总+ = 5.8;
System.out.println(total);
}
}

以上代码打印:

  11.399999999999 

我如何得到这个只是打印(或能够使用它)11.4?

解决方案

As其他人提到,您可能希望使用 BigDecimal 课程,如果您想具有11.4的确切代表。



现在,有一点解释为什么会发生这种情况:



float double Java中的原始类型是浮点数字,其中数字存储为二进制表示一个分数和一个指数。



更具体来说,一个双精度浮点值因为 double type是一个64位值,其中:




  • 1位表示符号(正或负)。

  • 指数的11位。

  • 有效数字的52位(小数部分为二进制)。



这些部分组合起来产生价值的 double 表示。



(来源:维基百科:双精度



有关如何在Java中处理浮点值的详细说明,请参阅第4.2.3节:浮点类型,格式和值的Java语言规范



字节 char int long 类型是定点号,这是数字的准确表示。与固定点数不同,浮点数将有一段时间(安全地假设大部分时间)不能返回数字的精确表示。这是因为$ code> 5.6 + 5.8 的结果 11.399999999999 的原因。



当需要一个确切的值(例如1.5或150.1005)时,您将需要使用其中一个定点类型,这些类型将能够准确地表示数字。 >

如前所述,Java已经有一个 BigDecimal 类将处理非常大的数字和非常小的数字。



从Java API参考中为 BigDecimal 类:




不变,
任意精度有符号的十进制
数字。 BigDecimal由
任意精度整数unscaled
值和32位整数值组成。如果
为零或正数,则刻度为
小数点右侧的位数
。如果为负数,则
的非标量值为
乘以10,以比例的
否定的幂。因此,
的值由
BigDecimal表示,因此(unscaledValue
×10 ^ -scale)。


有关浮点数及其精度问题的Stack Overflow有很多问题。以下是可能感兴趣的相关问题的列表:





如果你真的想下来对于浮点数的细节细节,请查看每台计算机科学家应该了解浮点数算术


public class doublePrecision {
    public static void main(String[] args) {

        double total = 0;
        total += 5.6;
        total += 5.8;
        System.out.println(total);
    }
}

The above code prints:

11.399999999999

How would I get this to just print (or be able to use it as) 11.4?

解决方案

As others have mentioned, you'll probably want to use the BigDecimal class, if you want to have an exact representation of 11.4.

Now, a little explanation into why this is happening:

The float and double primitive types in Java are floating point numbers, where the number is stored as a binary representation of a fraction and a exponent.

More specifically, a double-precision floating point value such as the double type is a 64-bit value, where:

  • 1 bit denotes the sign (positive or negative).
  • 11 bits for the exponent.
  • 52 bits for the significant digits (the fractional part as a binary).

These parts are combined to produce a double representation of a value.

(Source: Wikipedia: Double precision)

For a detailed description of how floating point values are handled in Java, see the Section 4.2.3: Floating-Point Types, Formats, and Values of the Java Language Specification.

The byte, char, int, long types are fixed-point numbers, which are exact representions of numbers. Unlike fixed point numbers, floating point numbers will some times (safe to assume "most of the time") not be able to return an exact representation of a number. This is the reason why you end up with 11.399999999999 as the result of 5.6 + 5.8.

When requiring a value that is exact, such as 1.5 or 150.1005, you'll want to use one of the fixed-point types, which will be able to represent the number exactly.

As has been mentioned several times already, Java has a BigDecimal class which will handle very large numbers and very small numbers.

From the Java API Reference for the BigDecimal class:

Immutable, arbitrary-precision signed decimal numbers. A BigDecimal consists of an arbitrary precision integer unscaled value and a 32-bit integer scale. If zero or positive, the scale is the number of digits to the right of the decimal point. If negative, the unscaled value of the number is multiplied by ten to the power of the negation of the scale. The value of the number represented by the BigDecimal is therefore (unscaledValue × 10^-scale).

There has been many questions on Stack Overflow relating to the matter of floating point numbers and its precision. Here is a list of related questions that may be of interest:

If you really want to get down to the nitty gritty details of floating point numbers, take a look at What Every Computer Scientist Should Know About Floating-Point Arithmetic.

这篇关于在Java中保持双精度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆