为什么程序可以在java或其他语言中精确显示无限重复的浮点数 [英] why program can exactly display infinite repeating floating point number in java or other language

查看:183
本文介绍了为什么程序可以在java或其他语言中精确显示无限重复的浮点数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如十进制数字0.1,表示为二进制0.00011001100110011 ....,这是一个无限重复的数字。
当我写这样的代码:

  float f = 0.1f; 

程序会将其舍入为二进制0 01111011 1001 1001 1001 1001 1001 101,这不是原始数字0.1。
但是当打印这个变量是这样的:

$ p $ System.out.print(f);

我可以得到原始数字0.1而不是0.100000001或其他数字。我认为程序不能完全代表0.1,但它可以精确显示0.1。如何做到这一点?



我通过添加二进制的每一位来恢复十进制数,它看起来很奇怪。

<$ p Math.pow(2,-4)+ Math.pow(2,-5)+ Math.pow(2,-8)+ Math.pow(2) (2,-12)+ Math.pow(2,-13)+ Math.pow(2,-16)+ Math.pow(2,-17)+ Math.pow( 2,-20)+ Math.pow(2,-21)+ Math.pow(2,-24)+ Math.pow(2,-25));

float f2 =(float)Math.pow(2,-27);

System.out.println(f);

System.out.println(f2);

System.out.println(f + f2);

输出:

0.099999994



7.4505806E-9

0.1

在数学, f1 + f2 = 0.100000001145 ...,不等于0.1。为什么程序不会像0.100000001那样得到结果,我认为这样更准确。

解决方案

Java的系统.out.print 打印足够的小数,如果解析为 double float ,转换为原来的 double float 值。

这是一个好主意,因为这意味着在某种意义上,这种转换为十进制的信息不会丢失。另一方面,它可以给你一个正确的印象,正如你在你的问题中所表明的那样,是错误的。

在其他语言中,你可以打印精确的十进制代表浮动双倍被考虑:

  #include< stdio.h> 

int main(){
printf(%。60f,0.1);



$ b $ p $结果:0.100000000000000005551115123125782702118158340454101562500000


在Java中,为了模拟上述行为,需要将 float double 转换为 BigDecimal (此转换是确切的),然后用足够的数字打印 BigDecimal 。 Java对浮点到字符串表示十进制转换的态度是普遍的,所以即使是 System.out.format 也是受影响。链接的Java程序(其重要行是 System.out.format(%。60f\\\
,0.1);
)显示 0.100000000000000000000000000000000000000000000000000000000 ,虽然 0.1d 的值不是 0.10000000000000000000 ...,并且Java程序员本可以原谅与C程序相同的输出。

将一个 double 转换为一个字符串,该字符串表示 double ,请考虑十六进制格式,Java 支持文字和打印。


like a decimal number 0.1, represented as binary 0.00011001100110011...., this is a infinite repeating number. when I write code like this:

float f = 0.1f;

the program will rounding it as binary 0 01111011 1001 1001 1001 1001 1001 101, this is not original number 0.1. but when print this variable like this:

System.out.print(f);

I can get original number 0.1 rather than 0.100000001 or some other number. I think the program can't exactly represent "0.1", but it can display "0.1" exactly. How to do it?

I recover decimal number through add each bits of binary, it looks weird.

float f = (float) (Math.pow(2, -4) + Math.pow(2, -5) + Math.pow(2, -8) + Math.pow(2, -9) + Math.pow(2, -12) + Math.pow(2, -13) + Math.pow(2, -16) + Math.pow(2, -17) + Math.pow(2, -20) + Math.pow(2, -21) + Math.pow(2, -24) + Math.pow(2, -25));

float f2 = (float) Math.pow(2, -27);

System.out.println(f);

System.out.println(f2);

System.out.println(f + f2);

Output:

0.099999994

7.4505806E-9

0.1

in math, f1 + f2 = 0.100000001145... , not equals 0.1. Why the program would not get result like 0.100000001, I think it is more accurate.

解决方案

Java's System.out.print prints just enough decimals that the resulting representation, if parsed as a double or float, converts to the original double or float value.

This is a good idea because it means that in a sense, no information is lost in this kind of conversion to decimal. On the other hand, it can give an impression of exactness which, as you make clear in your question, is wrong.

In other languages, you can print the exact decimal representation of the float or double being considered:

#include <stdio.h>

int main(){
  printf("%.60f", 0.1);
}

result: 0.100000000000000005551115123125782702118158340454101562500000

In Java, in order to emulate the above behavior, you need to convert the float or double to BigDecimal (this conversion is exact) and then print the BigDecimal with enough digits. Java's attitude to floating-point-to-string-representing-a-decimal conversion is pervasive, so that even System.out.format is affected. The linked Java program, the important line of which is System.out.format("%.60f\n", 0.1);, shows 0.100000000000000000000000000000000000000000000000000000000000, although the value of 0.1d is not 0.10000000000000000000…, and a Java programmer could have been excused for expecting the same output as the C program.

To convert a double to a string that represents the exact value of the double, consider the hexadecimal format, that Java supports for literals and for printing.

这篇关于为什么程序可以在java或其他语言中精确显示无限重复的浮点数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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