前言:
而今姐妹们对“内存中什么可以储存0或10”可能比较重视,各位老铁们都想要知道一些“内存中什么可以储存0或10”的相关知识。那么小编也在网上搜集了一些有关“内存中什么可以储存0或10””的相关内容,希望你们能喜欢,同学们一起来学习一下吧!1 整数在内存的的存储1.1 一个字节存储的数据范围
数据分为有符号和无符号两种
①无符号数:不考虑负数,也就是只有0和正数
0000 0000 ~ 1111 1111转换成十进制也就是0 ~ 255
因此一个字节存储无符号数的数据范围是0~255之间的256个整数
② 有符号数:考虑负数,也就是包含负数,0和正数
一个字节整数原码、反码和补码取值范围
十进制数字
原码
反码
补码
+127
0111 1111
0111 1111
0111 1111
...
...
...
...
+4
0000 0100
0000 0100
0000 0100
+3
0000 0011
0000 0011
0000 0011
+2
0000 0010
0000 0010
0000 0010
+1
0000 0001
0000 0001
0000 0001
+0
0000 0000
0000 0000
0000 0000
-0
1000 0000
1111 1111
0000 0000
-1
1000 0001
1111 1110
1111 1111
-2
1000 0010
1111 1101
1111 1110
-3
1000 0011
1111 1100
1111 1101
-4
1000 0100
1111 1011
1111 1100
...
...
...
...
-126
1111 1110
1000 0001
1000 0010
-127
1111 1111
1000 0000
1000 0001
-128
无
无
1000 0000
正数部分:0000 0000 ~ 0111 1111, 转换成十进制就是 0 ~ 127负数部分:1000 0001 ~ 1111 1111, 转换成十进制就是 -127 ~ -1特殊值:1000 0000,转换成十进制就是 -128,最高位既是符号位,又是数值位
因此一个字节存储有符号数的数据范围是-128 ~ 127之间的256个整数
使用计算器查看-128的补码表示方式
① 切换到程序员
② 选择一个字节(Byte)
③ 输入负整数十进制-128
④ -128的二进制补码是1000 0000
1. 编辑ByteLimit.java
package net.ittimeline.java.core.foundational.syntax.variable.type.primitive;/** * 一个字节存储的数据范围 * * @author tony 18601767221@163.com * @version 2024/10/15 9:13 * @since Java21 */public class ByteLimit { public static void main(String[] args) { //byte对应的包装类是Byte //调用Byte的静态常量(MAX_VALUE,MIN_VALUE)获取byte类型的取值范围 //调用Byte的静态常量BYTES获取byte类型占据的字节数 System.out.println("byte所能存储的最大值是" + Byte.MAX_VALUE + " byte所能存储的最小值是" + Byte.MIN_VALUE + " byte占据的内存空间是" + Byte.BYTES + "字节"); }}
2. 运行ByteLimit.java
程序运行结果
说明:Java的byte类型占据1个字节的内存空间,而且用于存储有符号整数,因此取值范围是-128~127 之间的256个整数
1.2 不同整数类型数据在内存中的存储
1. 编辑IntegerTypeStorage.java
package net.ittimeline.java.core.foundational.syntax.variable.type.primitive;/** * 不同整数类型数据在内存中的存储 * * @author tony 18601767221@163.com * @version 2024/10/15 9:14 * @since Java21 */public class IntegerTypeStorage { public static void main(String[] args) { byte byteVar = 3; System.out.println("byteVar = " + byteVar); short shortVar = 3; System.out.println("shortVar = " + shortVar); int intVar = 3; System.out.println("intVar = " + intVar); long longVar = 3; System.out.println("longVar = " + longVar); }}
2. 运行IntegerTypeStorage.java
程序运行结果
说明:虽然打印输出四种整数类型的变量存储的变量值都是3,但是它们在内存中占据的空间不同,因此存储形式也是不同,数据在内存中都是以二进制形式存储
1.3 正整数25和负整数-25在内存中的存储
整数底层使用二进制补码形式存储,要了解补码需要先了解原码和反码
原码:最高位是符号位,0表示正数,1表示负数,其他位表示数值位
例如一个字节(8个二进制位)整数25
25的原码:0001 1001-25的原码:1001 1001
反码:正数的反码与原码一致,负数的反码是原码的符号位不变,其他位取反
25的反码: 0001 1001-25的反码:1110 0110
补码:正数的补码与原码一致,负数的补码等于反码基础上加1
25的补码:0001 1001-25的补码:1110 0111
正整数25在内存中的存储
使用计算器查看正整数十进制25在计算机底层的存储
① 切换到程序员
② 切换到一个字节
③ 输入正整数十进制25
④ 正整数十进制25二进制补码是0001 1001
负整数-25在内存中的存储
使用计算器查看负整数十进制-25在计算机底层的存储
① 切换到程序员
② 切换到一个字节
③ 输入负整数十进制-25
④ 负整数十进制-25二进制补码是1110 0111
Integer类提供静态方法public static String toBinaryString(int i)查看整数的二进制表示方式
1. 编辑IntegerTypeToBinary.java
package net.ittimeline.java.core.foundational.syntax.variable.type.primitive;/** * 正整数25和负整数-25在内存中的存储 * * @author tony 18601767221@163.com * @version 2024/10/15 9:19 * @since Java21 */public class IntegerTypeToBinary { public static void main(String[] args) { //Integer类提供静态方法public static String toBinaryString(int i)查看整数的二进制表示方式 System.out.println("正整数25的二进制补码方式是" + Integer.toBinaryString(25)); System.out.println("负整数-25的二进制补码方式是" + Integer.toBinaryString(-25)); }}
2. 运行IntegerTypeToBinary.java
程序运行结果
说明:负整数-25默认占据四个字节,因此Integer.toBinaryString(int i)方法输出的32位二进制位,从右往左截取8位二进制位的结果是1110 0111
1.4 整数类型溢出的内存原理
1. 编辑IntegerTypeOverFlow.java
package net.ittimeline.java.core.foundational.syntax.variable.type.primitive;/** * 整数类型溢出的内存原理 * * @author tony 18601767221@163.com * @version 2024/10/15 9:21 * @since Java21 */public class IntegerTypeOverFlow { public static void main(String[] args) { /* 计算机在执行运算的时候使用补码运算 1. byte的表示范围是-128 ~ +127 2. 135超过了byte的表示范围,在强制类型转换的时候会发生溢出 3. 135 默认的类型是int int在内存中占据4个字节 1Byte=8bit 4个字节对应32位 4. 135 在内存的二进制补码表示方式 0000 0000 0000 0000 0000 0000 1000 0111 5. 因为135强制类型转换成byte 因此会从右往左截取8位,结果是1000 0111 6. 1000 0111 占据1个字节,但是符号位(左边第一位)是1表示该数字是一个负数 当我们查看计算机执行结果的时候使用原码 将1000 0111转换原码 1. 根据补码得到反码:补码减1 1000 0111-1=1000 0110 2. 根据反码得到原码:最高位不变,其他位取反 1000 0110 也就是 1111 1001 3. 将原码1111 1001 转换成十进制-121 4. 因此最后的结果是-121 */ byte value = (byte) 135; System.out.println("value = " + value); }}
2. 运行IntegerTypeOverFlow.java
程序运行结果
说明:给整数变量赋值时如果超过数据类型的取值范围就会造成数据溢出
2 小数在内存中的存储2.1 float和double在内存中的存储格式
如果你明白了小数在内存中的存储形式,那么就能够知道以下问题的答案
为什么4个字节的float比8个字节的long存储数据范围大为什么8个字节的double比四个字节的float精度更高为什么float和double会有精度问题
由于浮点数的存储机制和整数存储不一样,Java的浮点类型遵守IEEE754标准,采用二进制的科学计数法表示浮点数。
对于float,第1位是符号位,接下来8位表示指数位,接下来23位表示尾数位
对于double,第1位是符号位,接下来11位表示指数位,接下来52位表示尾数位
符号位:0表示正数,1表示负数指数位:把十进制小数转换为二进制小数形式,小数点(左右)移动到其左边只保留一位有效数字,小数点移动的位数加上127,得到指数位值。(左移位数为正,右移位数为负数)尾数部分:小数点右侧的小数部分的二进制表示
2.2 小数3.625在内存中的存储2.3 小数0.9在内存中存储2.4 查看浮点数的二进制表示float的包装类Float提供了静态方法 public static int floatToIntBits(float value)查看float类型小数的二进制表示方式double的包装类Double提供了静态方法public static long doubleToLongBits(double value)查看double类型小数的二进制表示方式
1. 编辑FloatTypeToBits.java
package net.ittimeline.java.core.foundational.syntax.variable.type.primitive;/** * 查看浮点数的二进制表示 * * @author tony 18601767221@163.com * @version 2024/10/15 9:30 * @since Java21 */public class FloatTypeToBits { public static void main(String[] args) { System.out.println("1.查看四个字节浮点数3.625和0.9的二进制表示"); float firstFloatValue = 3.625f; System.out.println("四个字节的浮点数3.625的二进制表示是" + Integer.toBinaryString(Float.floatToIntBits(firstFloatValue))); float secondFloatValue = 0.9f; System.out.println("四个字节的浮点数0.9的二进制表示是" + Integer.toBinaryString(Float.floatToIntBits(secondFloatValue))); System.out.println("2.查看八个字节浮点数3.625和0.9的二进制表示"); double firstDoubleValue = 3.625; System.out.println("八个字节的浮点数3.625的二进制表示是" + Long.toBinaryString(Double.doubleToLongBits(firstDoubleValue))); double secondDoubleValue = 0.9; System.out.println("八个字节的浮点数0.9的二进制表示是" + Long.toBinaryString(Double.doubleToLongBits(secondDoubleValue))); }}
2. 运行FloatTypeToBits.java
程序运行结果
3 字符在内存中的存储3.1 ASCII字符编码字符在内存中存储
ASCII字符集使用ASCII字符编码存储字符,使用一个字节存储字符,ASCII字符编码二进制左边第一位是0
ASCII字符
码点(编号)
存储格式(二进制)
'a'
97
0110 0001
'A'
65
0100 0001
'0'
48
0011 0000
' '
32
0001 0000
'\n'
10
0000 1010
'\t'
9
0000 1001
1. 编辑ASCIICharacterToBinary.java
package net.ittimeline.java.core.foundational.syntax.variable.type.primitive;import java.nio.charset.Charset;/** * ASCII字符编码字符在内存中存储 * * @author tony 18601767221@163.com * @version 2024/10/15 9:35 * @since Java21 */public class ASCIICharacterToBinary { public static void main(String[] args) { //Charset.defaultCharset()用于获取当前JVM使用的编码 //UTF-8编码兼容ASCII System.out.println("当前JVM使用的编码是" + Charset.defaultCharset()); /**********************ASCII字符集常用字符的编码**********************/ char lowercaseLetterA = 'a'; //(int) lowercaseLetterA 表示将字符类型转换为int类型,这样就可以获取字符对应的编码 System.out.println("字符" + lowercaseLetterA + "对应的编码是 " + (int) lowercaseLetterA + " 二进制存储形式是" + Integer.toBinaryString(lowercaseLetterA)); char uppercaseLetterA = 'A'; //(int) uppercaseLetterA 表示将字符类型转换为int类型,这样就可以获取字符对应的编码 System.out.println("字符" + uppercaseLetterA + "对应的编码是 " + (int) uppercaseLetterA + " 二进制存储形式是" + Integer.toBinaryString(uppercaseLetterA)); char zero = '0'; //(int) zero 表示将字符类型转换为int类型,这样就可以获取字符对应的编码 System.out.println("字符" + zero + "对应的编码是 " + (int) zero + " 二进制存储形式是" + Integer.toBinaryString(zero)); char space = ' '; //(int) space 表示将字符类型转换为int类型,这样就可以获取字符对应的编码 System.out.println("字符" + space + "对应的编码是 " + (int) space + " 二进制存储形式是" + Integer.toBinaryString(space)); //\n表示换行转义字符 char newLine = '\n'; // (int) newLine 表示将字符类型转换为int类型,这样就可以获取字符对应的编码 System.out.println("字符'换行符'对应的编码是 " + (int) newLine + " 二进制存储形式是" + Integer.toBinaryString(newLine)); //\t表示tab转义字符 char tab = '\t'; // (int) tab 表示将字符类型转换为int类型,这样就可以获取字符对应的编码 System.out.println("字符'制表符'对应的编码是 " + (int) tab + " 二进制存储形式是" + Integer.toBinaryString(tab)); }}
2. 运行ASCIICharacterToBinary.java
程序运行结果
说明:Integer.toBinaryString(int i)查看整数二进制补码,如果整数是正整数时会省略二进制前面若干个0
3.2 UTF-8字符编码在内存中存储
Unicode字符集也称为统一码、标准万国码,是国际组织制定的,可以容纳世界上所有文字、符号的集合。
Unicode字符集的广泛应用促进了跨语言、跨平台文本信息的无缝交换,使得在互联网和全球化软件开发中,不同语言的文字能够共存并正确显示。
Unicode字符集有三种编码方案,UTF-8、UTF-16和UTF-32,最为常用的UTF-8字符编码。
UTF-8编码,可以用来表示Unicode标准中任何字符,它是电子邮件、网页及其他存储或传送文字的应用中优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码,所以我们开发Web应用也要使用UTF-8编码。
它使用一至四个字节(可变长度)为每个字符编码,编码规则如下:
128个US-ASCII字符,只需一个字节编码,兼容ASCII编码拉丁文、希腊文、阿拉伯文等字符,需要两个字节编码大部分常用字(中文、俄文、韩文、日文)使用三个字节编码。其他极少使用的Unicode辅助字符,使用四个字节编码
UTF-8还规定Unicode字符集对应的二进制存储方式
字节数
二进制存储方式
说明
1个字节
0xxx xxxx (ASCII码)
第一个字节开头必须是0
2个字节
110xxxx 10xxxxxx
第一个字节开头必须是110,第二个字节开头必须是10
3个字节
1110xxxx 10xxxxxx 10xxxxxx
第一个字节开头必须是1110,第二个、第三个字节开头必须是10
4个字节
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
第一个字节开头必须是11110,第二个、第三个、第四个字节开头必须是10
UTF-8编码存储m我a
字符
UTF-8码值(字符编号)
二进制
UTF-8编码存储格式
m
109
0110 1101
0110 1101
我
25105
110 001000 010001
11100110 10001000 10010001
a
97
0110 0001
0110 0001
1. 编辑UnicodeCharacterToBinary.java
package net.ittimeline.java.core.foundational.syntax.variable.type.primitive;import java.nio.charset.Charset;/** * UTF-8字符编码在内存中存储 * * @author tony 18601767221@163.com * @version 2024/10/15 9:36 * @since Java21 */public class UnicodeCharacterToBinary { public static void main(String[] args) { //Charset.defaultCharset()用于获取当前JVM使用的编码 //UTF-8编码兼容ASCII System.out.println("当前JVM使用的编码是" + Charset.defaultCharset()); String str = "m我a"; //使用平台默认的字符编码将字符串编码为一系列字节,即使用UTF-8编码的方式将字符串转为字节数组 byte[] bytes = str.getBytes(); //遍历字节数组,获取每个字节 for (int i = 0; i < bytes.length; i++) { System.out.printf("第%d个字节内容是%d\n", i + 1, bytes[i]); } /* 第1个字节内容是109 第2个字节内容是-26 第3个字节内容是-120 第4个字节内容是-111 第5个字节内容是97 */ /* 109, -26, -120, -111, 97是怎么来的? UTF-8编码下英文字母占据1个字节,109是字符m在内存存储的十进制表示方式, 97是字符a在内存存储的十进制表示方式 UTF-8编码下中文占据3个字节,-26, -120, -111是字符我在内存存储的十进制表示方式 */ //(int) 'm' 表示将字符字面量m转换为int类型,其目的就是获取m对应的编码109 System.out.println("字符m对应的编码是 " + (int) 'm'); //(int) 'a' 表示将字符字面量a转换为int类型,其目的就是获取a对应的编码97 System.out.println("字符a对应的编码是 " + (int) 'a'); //(int) '我' 表示将字符字面量a转换为int类型,其目的就是获取a对应的编码25105 System.out.println("字符我对应的编码是 " + (int) '我'); // 获取字符我对应编码的二进制表示方式是110001000010001 System.out.println("字符我对应的编码二进制表示方式是 " + Integer.toBinaryString('我')); /* 一个字节表示八个二进制位 UTF-8编码规定 第一个字节开头必须是1110,第二个、第三个字节开头必须是10 字符我对应编码的二进制表示方式是110 001000 010001 因此第一个字节是1110 0110 第二个字节是1000 1000 第三个字节是1001 0001 数据的存储、计算都是补码,数据的打印输出是原码 第一个字节1110 0110 转换为原码并转换成十进制 补码:1110 0110 反码:1110 0101 原码:1001 1010 001 1010转换为十进制结果是-26 第二个字节是1000 1000转换为原码并转换成十进制 补码:1000 1000 反码:1000 0111 原码:1111 1000 1111 1000转换为十进制的结果是-120 第三个字节是1001 0001转换为原码并转换成十进制 补码:1001 0001 反码:1001 0000 原码:1110 1111 1110 1111转换为十进制的结果是-111 */ }}
2. 运行UnicodeCharacterToBinary.java
程序运行结果
标签: #内存中什么可以储存0或10 #内存用于存储 #内存中什么可以存储0或1 #内存如何存储0和1