为什么一个byte的存储范围是-128~127?

为什么一个byte的存储范围是-128~127?
文本关键字:byte、字节、二进制位、反码、补码
文章目录
为什么一个byte的存储范围是-128~127?

一、byte

二、反码与补码

**1. 反码

  1. 补码
    三、byte的数据范围
    一、byte**
    在计算机中,一个二进制位是最小的存储单元,由于是二进制,所以能存储的数字只能是0和1。显然,如果我们直接去操作每个二进制位将是很麻烦的过程,所以在编程中我们直接使用的是其他的数据类型,如:byte、int、float。这些数据类型能够使我们的数据存储更加方便,我们只需要关心他们能够存储多大范围和什么样类型的数据就可以了。
    那么一个byte,也就是我们所说的一字节,他所占用的空间是8个二进制位。

1 byte = 8 bit(比特)
这8个bit就是8个二进制位,其中有一个是符号为,刚好可以用0和1来代表正负。那么这8个二进制位到底能够表示多大范围的数字呢?对于正数的进制转换相信难不倒大家,也可以参考底部的相关文章,我们先来看一下负数在二进制下是如何表示和转换的。

二、反码与补码
首先把公式立在这里:

正数的补码 = 原码 = 反码
负数的补码 = 反码 + 1
那么首先什么是原码呢?很简单,在我们不考虑符号的情况下,按照进制的转换方法将一个十进制数转换为二进制数,再添加上相应的符号位就完成了。符号位出现在最前(左)面一位,0代表正数,1代表负数。

+3 -> 11 -> 根据符号和byte长度补全:0000 0011
-5 -> 101 -> 根据符号和byte长度补全:1000 0101
那么为什么会提出反码和补码的概念呢?有两个原因:

1. 反码
保证在二进制下能够正常的进行正负数间的运算。

首先我们来看一下如果直接使用原码存储,在进行正负数运算的时候会出现什么样的情况。5+(-3)=2,那么在二进制下的运算也和十进制一样,直接相加,该进位进位,但是符号位没法直接参与运算,换句话说,让计算机直接判断算式最后的正负其实比较困难。
原码计算:0000 0011 + 1000 0101 = 1000 1000,结果是:-8(不需要纠结最后的符号位应该取什么,因为在计算机中并没有采用这种方法进行计算,只是举例)。显然,直接采用原码计算的这种方式在正数下是没问题的,但是在负数时就不适用了,所以我们需要重新定义一个规则对负数进行处理。
由于在正数下计算是没问题的,那么就可以规定:正数的反码等于原码,负数的反码为除去符号位,其他取反。

+3 -> 原码:0000 0011 -> 反码:0000 0011
-5 -> 原码:1000 0101 -> 反码:1111 1010
反码计算后:1111 1101 -> 原码:1000 0010 -> 十进制:-2。嗯,好像没什么问题了,但是当一个正数和一个负数的运算结果为正数(如:+5和-3,大家可以自己验证)或者恰好为0时还是会有问题。

2. 补码
+0和-0的冲突问题。

从相反数的概念我们可以知道,一个正数肯定存在一个与之对应的相反数,对于整数来说我们只要直接改变一下符号位就行了。But!这个0就很特殊,有一个耳熟能详的概念:0的相反数还是0,这会直接导致进制的转换不是一一对应的关系了。

+2 -> 原码:0000 0010 -> 反码:0000 0010
-2 -> 原码:1000 0010 -> 反码:1111 1101
反码计算后:1111 1111 -> 原码:1000 0000 -> 十进制:-0。结果貌似正确,但是在正数中:0000 0000也同样代表0。那么对于1000 0000,是不能直接被抹去的,那就让它来代表一个特殊的数字吧:-128。
其实,特殊的不只是这一个数字,如对于Java中的short,占用两个字节,最高一位为符号位,那么就会出现这个数字:1000 0000 0000 0000,从原码上看也是-0,对于int类型也是一样,那么这个问题就可以总结为:符号位为1,其他位均为0,我们应该怎么处理。
于是,为了解决这一类问题,就有了补码的概念:负数的补码 = 反码 + 1。我们用临界位置的计算来进行举例,如:(-2)+(-126)=-128。

-2 -> 原码:1000 0010 -> 反码:1111 1101 -> 补码:1111 1110
-126 -> 原码:1111 1110 -> 反码:1000 0001 -> 补码:1000 0010
补码运算结果:1000 0000(该类数字没有原码和反码)
到此我们该敲个黑板,划个重点了:在内存中都是使用补码来进行计算的(整数类型)!

三、byte的数据范围
明确了上面几个概念,那么byte的范围应该就很清楚了。

最大的正数:0111 1111 -> 2^7 - 1 = 127
最大的负数:1000 0000 -> -2^7 = -128
对于其他正数类型的范围也是如此:

Java中的short:2字节 -> -2^15 ~ 2^15 - 1
Java中的int:4字节 -> -2^31 ~ 2^31 - 1
Java中的long:8字节 -> -2^63 ~ 2^63 - 1
不同语言定义的数据类型在内存中占用的字节数是不同的,而且也不需要直接记这些范围,一般来说记字节就好。

原文地址:https://blog.51cto.com/14639282/2457918

时间: 2024-11-19 22:15:07

为什么一个byte的存储范围是-128~127?的相关文章

java byte为何范围是-128~127

从我们接触Java的时候,就被告知基础类型byte是一个字节,占8位,表示的范围是-128~127.那么为什么会这个范围呢? ??咱们先回顾一下计算机基础: 1. 在计算机内部数据的存储和运算都采用二进制:2. 计算机中数据分为有符号数和无符号数,对于有符号数,计算机规定用最高位来表示符 号."0"表示正数,"1"表示负数:3. Java中的数据都是有符号数:4. 计算机中带符号的整数都是使用二进制的补码. 这里提到了一个概念补码,那么就得补充原码和反码.[原码]:

byte的取值范围为什么是-128~127

直接给总结:计算机规定了0000 0000 代表0,1000 0000代表的-0没有意义,必须找个~127~127之外的数和它对应,「人为规定-0就是-128」,而且这么做完美适合计算机做减法运算. 来我们一步步分析分析: 1.byte占用8位,每位用0或1表示,能够表示256(2^8)个数据. 2.这8位分为符号位(最高位)和数值位(剩余七位),符号位0表示正数,1表示负数. 3.按上一步的理解,容易得到(+127:0111 1111.+1:0000 0001.+0:0000 0000.-0:

一个byte缓存--用于图片或视频

public class ImageCache { private List<byte[]> list = new ArrayList<byte[]>(); //存储所有部分缓存 private int initSize;    //初始化大小,每次申请时都会申请等同于initSize大小的byte[] buf private int size;    //image cache 的实际大小 public ImageCache(int initSize){ this.initSiz

为什么数值类型byte取值范围是(-128~127)?

在解决这个问题之前,我们先了解几个概念? 一.原码, 反码, 补码的概念 正数的反码和补码都与原码一样: 负数的反码.补码与原码不同,负数的反码:原码中除去符号位,其他的数值位取反,0变1,1变0.负数的补码:其反码+1. 做个小Demo,分别写出7和-7的原码.反码.补码.(其中第一位是符号位,0表示正数,1表示负数) Demo 7 -7 原码 00000111 10000111 反码 00000111 11111000 补码 00000111 11111001 一. 机器数和真值 在学习原码

java中基本数据类型数据转化成byte[]数组存储

java中基本数据类型数据转化成byte[]数组存储 1 package com.wocqz.test; 2 3 public class testByte { 4 5 /** 6 * int 转成byte数组 7 * */ 8 public static byte[] int_byte(int id){ 9 //int是32位 4个字节 创建length为4的byte数组 10 byte[] arr=new byte[4]; 11 12 arr[0]=(byte)((id>>0*8)&

ByteBuffer: 当由一个byte[]来生成一个固定不变的ByteBuffer时,使用ByteBuffer.wrap(byte[]);

StringBuilder sb = new StringBuilder(1024); //向sb中写入900个左右的随机字符内容 for(int j=1; j< 50;j++) { sb.append(Math.random()); } //System.out.println("sb:" + sb.length()); long startTime = System.currentTimeMillis(); for(int i=0;i<10000;i++) { /* b

android开发:把一个byte数组转换成wav音频文件,并且播放

============问题描述============ 如题,byte数组转换成wav音频文件,并且播放,下面代码能生成data/data/com.example.playwav/cache/temp.wav 但是在播放的时候报异常. 我把代码和Log贴在下面了. 我分析,原因应该是wav文件格式的编解码问题,不能这么随随便便把任意的一个byte数组就转化为了wav 希望了解wav编解码开发的童鞋给点解决办法 byte[] a = { 52, 51, 48, 28, 58, 64, 98,-1

如果系统要使用超大整数(超过long长度范围),请你设计一个数据结构来存储这种超大型数字以及设计一种算法来实现超大整数加法运算

package interview_10_10; import org.junit.Test; public class T1 { /** * 如果系统要使用超大整数(超过long长度范围),请你设计一个数据结构来存储这种超大型数字以及设计一种算法来实现超大整数加法运算). */ @Test public void test1() { String number1 = "4324328732789"; String number2 = "2383244324324325898

5.oracle中一个字段中存储&#39;a&#39;,&#39;b&#39;与&#39;a&#39;与a的写法,存储过程中与之对应

select '''a'',''b''' from dual; --'a','b' select '''a''' from dual; --'a' select 'a' from dual; --a 5.oracle中一个字段中存储'a','b'与'a'与a的写法,存储过程中与之对应