Java基础类型

img

  • Java是一种强类型的语言
  • 而且我们的Java有一种能够表示任意精度的算数包,通常称为大数,但是他是对象

整型变量 int

基本语法格式

int a=10;//初始化时并赋值
int a;

内存大小

int 大小为4个字节(byte),与操作系统的和JVM的版本无关,像C语言可能就会受到编译器的影响,是为了实现跨平台

整型的范围

  • 也就是-231至231-1
  • 因为4字节表示有32位,一位用来表示正负

数据溢出问题

img

为什么会溢出

img

因为2^32-1的数据的大小不够用,还不够表述出马云的个人资产,所以引出了long类型

长整型 long

long a=10L;
long a=10l;
long a=1000_000_000;//可以为数字字面量加下划线,这些下划线只是让人更易读,Java编译器会自动去除这些下划线

为什么要加L呢?

字面量 ——程序中直接写出来的值

image-20221101221833700

整型的字面量,默认是整型(int),浮点数的字面量,默认是double,所以要加一个L(l)表示它是long类型,否则会发生隐式转换

内存的大小

long类型的大小是8字节

long的数据范围

-263至263-1

短整型 short

short a=20;

内存大小

2个字节 数值范围是 -215至-215-1

基本没啥用

比特型 byte

byte a=1;

内存大小

一个字节 ,数值访问 -128到127

主要用于文件和网络的传输

浮点数 float和double

float f=1.2f;
float f=1.2F;
double d=1.2;

在JAVA中直接写出来的字母常量的浮点数都是double类型的,所以在flaot需要特别的声明一下

内存大小

float的大小为4个字节,double的字节是8个字节 在内存中采用指数的形式来模拟

浮点数存储规则

根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:

(-1)^S * M * 2^E

  • (-1)^S S表示符号位,当s=0,V为正数;当s=1,V为负数。
  • M表示有效数字,大于等于1,小于2。
  • 2^E E表示指数位。

举例来说:

十进制的5.0,写成二进制是 101.0 ,相当于 1.01×2^2 。

那么,按照上面V的格式,可以得出s=0,M=1.01,E=2。

十进制的-5.0,写成二进制是 -101.0 ,相当于 -1.01×2^2 。那么,s=1,M=1.01,E=2。

IEEE 754规定:

  • 对于32位的浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。

https://img2018.cnblogs.com/blog/1070689/201903/1070689-20190310165139947-1347641585.png

  • 对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。img

IEEE 754对有效数字M和指数E,还有一些特别规定。

  • 前面说过, 1≤M<2 ,也就是说,M必须写成 1.xxxxxx 的形式,其中xxxxxx表示小数部分。
  • IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的 xxxxxx部分。比如保存1.01的时 候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。以32位 浮点数为例,留给M只有23位, 将第一位的1舍去以后,等于可以保存24位有效数字。

至于指数E,情况就比较复杂。

  • 首先,E为一个无符号整数(unsigned int)
  • 这意味着,如果E为8位,它的取值范围为0255;如果E为11位,它的取值范围为02047。但是,我们知道,科学计数法中的E是可以出现负数的,所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数 是127;对于11位的E,这个中间 数是1023。比如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即 10001001。

然后,指数E从内存中取出还可以再分成三种情况:

E不全为0或不全为1

这时,浮点数就采用下面的规则表示,即指数E的计算值减去127(或1023),得到真实值,再将 有效数字M前加上第一位的1。

比如:0.5(1/2)的二进制形式为0.1,由于规定正数部分必须为1,即将小数点右移1位,则为1.0*2^(-1),其阶码为-1+127=126,表示为 01111110,而尾数1.0去掉整数部分为0,补齐0到23位00000000000000000000000,则其二进 制表示形式为:img

E全为0

这时,浮点数的指数E等于1-127(或者1-1023)即为真实值, 有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于0的很小的数字。

E全为1

这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s);

关于3*0.1==0.3

  • 答案是不相同的

  • 在上面,我们知道我们的浮点数在计算机以指数形式存储,其原理还是得用我们的二进制来表示

    • 比如0.75 可以用 2-1+2-2来表示 0.11 1.1*2^-1 在计算机中变成 S=0 E=-1+127 M=1
    • 但是这个0.1我们是不能用二进制位精确表达出来的,所以肯定会存在误差

    image-20221101230442692

如何解决

  • 仍使用double类型,但是只看小数前6位,后面的忽略不计
  • 使用BigDecimal来代替double使用

如果的基本整数和浮点数的精度不能满足需求,可以使用java.math包下两个很有用的类

  1. BigInteger 实现任意精度的整数运算

    • BigInteger a=new BigInteger(“123”); //第一种,参数是字符串
    • BigInteger a=BigInteger.valueOf(123); //第二种,参数可以是int、long
  2. BigDecimal 实现任意精度的浮点数运算

    • BigDecimal 常用的构造方法如下。

      • BigDecimal(double val):实例化时将双精度型转换为 BigDecimal 类型。

      • BigDecimal(String val):实例化时将字符串形式转换为 BigDecimal 类型。

    BigDecimal add(BigDecimal augend)    // 加法操作
    BigDecimal subtract(BigDecimal subtrahend)    // 减法操作
    BigDecimal multiply(BigDecimal multiplieand)    // 乘法操作
    BigDecimal divide(BigDecimal divisor,int scale,int roundingMode )    // 除法操作
    

    image-20221101235259115

字符型 char

char a='a';
char b='A';
char c='哈';

内存大小

  • 占两个字节,在C中是一个字节,而且它可以存储中文

  • 这是C做不到的C言中使用 ASCII 表示字符, 而 Java 中使用 Unicode 表示字符. 因此一 个字符占用两个字节, 表示的字符种类更多, 包括中文

  • 在Java中,char类型表示的是UTF-16的一个代码单元,而不是Uncoide的字符 字符集和char的关系

布尔类型 boolean

boolean b=true;
boolean b=false;

注意点

  • boolean只有两个值,真就是true,假就是false

  • Java 的 boolean 类型和 int 不能相互转换 , 不存在 1 表示 true, 0 表示 false 这样的用法

  • 如何将boolean变成0或者1

  • boolean类型在我们的官方文档写的是 It's virtual machine dependent. // 由虚拟机自己实现

    • 我们都知道,Java语言中有个boolean类型。每个boolean类型的变量中存储的是一个true或者是false的逻辑值。那么存储这个逻辑值,需要多大的空间呢?从理论上来讲,存储这个逻辑值只需要1个位(bit)就可以了,所以很多教科书上谈到这个问题的时候,也说boolean类型的数据在内存中只占1个位。
    • 但是稍微有点计算机常识的人都知道:计算机完成寻址操作的时候,是以字节为最小单位进行的。也就是说每次要读取内存中数据的时候,最小只能精确到1个字节,不能单独读取某个位上的信息。如果boolean类型的变量的值只占1个位,计算机每次读取到1个字节的信息,里面会包含8个boolean变量的值。计算机就不得不通过某种算法去确定这8个值中,哪一个才是我们要找的值。这样做显然非常不合理,因为要完成这个“8选1”的操作又会增加运算工作量。那么Java虚拟机到底是怎样存储boolean值呢?
    • 在《虚拟机规范》中,对boolean类型的存储有专门的解释,文中说到:“虽然定义了boolean这种数据类型,但是只对它提供了非常有限的支持。在Java虚拟机中没有任何供boolean值专用的字节码指令,Java语言表达式所操作的boolean值,在编译之后都使用Java虚拟机中的int数据类型来代替而boolean数组将会被编码成Java虚拟机的byte数组,(因此)每个boolean元素占8位”。
    • 变成int类型,是因为我们很多的CPU都是32位,这样的存取效率是最高的
posted @ 2022-11-01 23:54  刘颂成  阅读(51)  评论(0编辑  收藏  举报