java float赋值两种_java中为为什么给float类型变量赋值需要加F,而给byte、short赋值的时候却不需要呢?...

也是想到了这个问题,然后google到了这个知乎的讨论,看完大家的回答感觉都不能说服我。但是翻R大的一篇回答恍然大悟。Java基本类型的物理存储大小---R大的回答​hllvm.group.iteye.com

和 @北南 的回答相似。

JVM规范中所说,并没有说float,int,byte等占多少个字节,而是真正的有效位是多少。比如byte的有效位是1个字节,也就是-128到127。使用Java编程的时候,就只能用byte表示-128到127之间的数,而真正JVM实现,一般byte还是占用和int一样大小:4个字节。

也就说在JVM看来,short,byte,int都是同一个东西。

这也就解释了为什么byte,short使用int字面量赋值的时候会不用强制转型。

short a=3;

byte b =2;

因为编译器在编译的只需要根据字面值3,字面值2来确定是否超过有效值即可,并不用做深入的检查,因为他们在JVM存在的类型也是一样的。

byte b=128; //error

同时在通过JVM在操作byte,short,int都是用的相同的指令:iconst,bipush等也能证明。

然而double和float在JVM中存储是不一样的。

System.out.println(3.2f==3.2d);//false

因此在使用double给float赋值的时候,会报错的。

以上,都是猜测。

嗯,昨天回去又仔细研读了R大的回答,感觉拿来做这个问题的回答确实有点牵强。

其实研究下浮点数可以知道0.1+0.2≠0.3 的问题。

同理由于float 和 double的精确度不一样,会带来确确实实的精度损失。

比如:

float a=5.8f

使用IEEE754标准 表示为:1.45*2^2

也就是:

0(符号位 0) 10000001(指数位129) 01 1100 1100 1100 1100 1100 1(尾数 0.45)

由于尾数0.45使用二进制表示是无限循环,而IEEE754标准单精度表示尾数为23位。

而:

double a=5.8

在IEEE754标准中,double尾数为52位.

这样的赋值确确实实是引起了精度变化。就好像同时使用0.99和0.9999来表示1一样。

而这样的精度损失存在的情况很多。

所以如果和整型一样如果让编译器帮你判断是不是有精度损失就会出现一会需要加后缀,比如

float a=5.8f

一会又不需要添加后缀

float a=4;

因此必须使用double赋值给float就表示,我接收这种精度损失。

而反观int , short ,byte

只要不超出范围,他们值确实是一样的。就好像

byte a=128; //error : required int ,found byte

一样,编译器照样会告诉你,你超过范围了!!!

至于最开始的回答,贴出来的链接还是可以看看的,至少能帮助理解操作数栈的slot的大小以及为什么JVM在加载byte,short操作数的时候,都是用的和int一样的指令。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值