什么是java浮点型_学习java浮点型的一些细节

出自《Java深入解析》的例子

例1、先看一段代码:

public static voidmain(String[] args) {double d1 = 0.1;double d2 = 0.2;

System.out.println("" + d1 + "+" + d2 + "=" + (d1 +d2));

}

初学者可能脱口而出执行的结果是输出 d1+d2=0.3。但是结果却没有这么简单:

0.1+0.2=0.30000000000000004

转念一想,却也没有一点玄妙。

二进制只能表示十进制中诸如0.5,0.25,0.125之类的小数。

十进制中可以表示0.1~0.9的小数,却不能表示1/3这样的分数。以此类推需要表示1/3,可能3进制更能胜任。

例2、BigDecimal是用来表示精度较大的小数的类,用二进制的数据表示十进制数可以说真是强人所难了。

for (int i = 1; i <= 9; i++) {double d = Double.parseDouble("0."+i);

System.out.println(d);

BigDecimal bd= newBigDecimal(d);

System.out.println(bd);

}

结果:

0.1

0.1000000000000000055511151231257827021181583404541015625

0.2

0.200000000000000011102230246251565404236316680908203125

0.3

0.299999999999999988897769753748434595763683319091796875

0.4

0.40000000000000002220446049250313080847263336181640625

0.5

0.5

0.6

0.59999999999999997779553950749686919152736663818359375

0.7

0.6999999999999999555910790149937383830547332763671875

0.8

0.8000000000000000444089209850062616169452667236328125

0.9

0.90000000000000002220446049250313080847263336181640625

例3.不如做个测试,看看计算机“偏爱”什么样的数字吧。

1 /**

2 * 测试0.0001~0.9999范围内的小数那些可以被二进制准确表示3 **/

4 public classFloatStorage {5

6 public static voidmain(String[] args) {7 int limit = 9999;//测试的范围0.0001-0.9999

8 int length = String.valueOf(limit).length();//小数的位数

9

10 System.out.println("在0.0001~0.9999之间可以被准确表示的小数有");11

12 for (int i = 1; i <= 9999; i++) {13 int significance = String.valueOf(i).length();//小数的非0数位

14 int zero = length - significance;//小数的0数位

15 StringBuilder sb = new StringBuilder("0.");//建立字符串

16 for (int j = 1; j <= zero; j++) {17 sb.append(0);18 }19 sb.append(i);20 BigDecimal bd = new BigDecimal(Double.parseDouble(sb.toString())/*得到二进制数*/);21 if (bd.scale() <= length) {//如果符合我们的要求,输出

22 System.out.println(bd);23 }24 }25 }26

27 }

运行结果:

在0.0001~0.9999之间可以被准确表示的小数有0.0625

0.125

0.1875

0.25

0.3125

0.375

0.4375

0.5

0.5625

0.625

0.6875

0.75

0.8125

0.875

0.9375

真是寥寥无几啊!

如果小结一下浮点数的特点,原来浮点数和小数之间还是有一定的差别,

在赋值或者存储中浮点类型的精度有限,

同时在计算机实际处理和运算过程中,浮点数本质上是以二进制形式存在的。

二进制所能表示的两个相邻的浮点值之间存在一定的间隙,浮点值越大,这个间隙也会越大。

如果此时对较大的浮点数进行操作时,浮点数的精度问题就会产生,甚至出现一些“不正常"的现象。

例4

public classBigFloat {public static voidmain(String[] args) {float f1 =30000f;float f2 = f1 + 1;

System.out.println("f1:" +f1);

System.out.println("f2:" +f2);if (f1

System.out.println("f1

}else{

System.out.println("f1

}float f3 =30000000f;float f4 = f3 + 1;

System.out.println("f3:" +f3);

System.out.println("f4:" +f4);if (f3

System.out.println("f3

}else{

System.out.println("f3

}

}

}

运行的结果:

f1:30000.0f2:30001.0f1

f3:3.0E7f4:3.0E7f3

一个数加一不比原来的数大,这就是由于精度产生的现象了。

例5

float可以保留7-8位有效数字

int a = 1;int b = 123;int c = 1234;int d = 12345;int e = 123456;int f = 1234567;int g = 12345678;int h = 123456789;int i = 1234567891;long j = 12345678912L;long k = 123456789123L;long l = 1234567891234L;long m = 12345678912345L;

System.out.println((float)a);

System.out.println((float)b);

System.out.println((float)c);

System.out.println((float)d);

System.out.println((float)e);

System.out.println((float)f);

System.out.println((float)g);

System.out.println((float)h);

System.out.println((float)i);

System.out.println((float)j);

System.out.println((float)k);

System.out.println((float)l);

System.out.println((float)m);

结果为:

1.0

123.0

1234.0

12345.0

123456.0

1234567.0

1.2345678E7

1.23456792E8

1.23456794E9

1.23456788E10

1.23456791E11

1.23456795E12

1.2345679E13

double类型可以保留15-16位有效数字

System.out.println((double)a);

System.out.println((double)b);

System.out.println((double)c);

System.out.println((double)d);

System.out.println((double)e);

System.out.println((double)f);

System.out.println((double)g);

System.out.println((double)h);

System.out.println((double)i);

System.out.println((double)j);

System.out.println((double)k);

System.out.println((double)l);

System.out.println((double)m);

结果为:

1.0

123.0

1234.0

12345.0

123456.0

1234567.0

1.2345678E7

1.23456789E8

1.234567891E9

1.2345678912E10

1.23456789123E11

1.234567891234E12

1.2345678912345E13

个人猜想:

强制类型转换如long到int,是截取高位的,一个正的long有可能转成一个负的int类型。

而整型到浮点型的转换是忽略低位的精度,相对说比较稳定。

因此前者需要强制类型转换,而后者可以进行自动类型转换。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值