Java中负数以及类型转换问题

学习过java的都知道,在java中,不是直观的表示负数,而是采用补码的形式表示负数。

这是为了硬件操作的方便,把减法也转换成加法来运算。
那补码是怎样表示的呢?为了得到补码,我们引入了反码。

对于正数来讲,它的反码补码都为本身,如果不明白为什么,我们可以这样理解:引入反码补码的原因就是为了解决减法的问题,换句话数就是解决java中负数的问题,正数不存在这些问题,所以它的反码补码就是它本身。在有符号的基本数据类型中,最高位0表示正数,最高位1表示负数。 对于负数来讲,它的反码就是除去符号位取反,然后加1就得到了它的补码。
这里举个简单的例子,一个byte型数据,它在计算机中占8位,-7可以表示为10000111,最高位的1代表负号,它的反码是除去符号位各位取反为11111000,然后加1得到补码11111001。

8的二进制表示为00001000,现在我们运算8 - 7,在计算机并不是用8减去7,而是用8 + (-7),也就是用00001000加上-7的补码11111001,两个有符号数相加,如果符号位相加有近位就删去符号位的进位,得到00000001,也就是1.
java中我们经常也会遇到不同数据类型的转换,这是最容易出错的地方。

首先我们了解一下什么是符号扩展,对于正数来讲,在前面补0; 负数时在前面补1。比如8位的二进制数10000111扩展为16位,我们在前面加上8个1,1111111110000111;如果是正数,则在前面补0。这样进行扩展后,符号和数值的大小都不变。
接下来我们我们看一下不同类型之间是怎样转换的,首先我们要知道这些基本类型各自占几位。 有符号型: byte = 8   int = 32   short = 16 long = 64   float = 32   double = 64   *boolean 只占一位,用0和1代表false和true。
无符号型: char =  16
1. byte型转为char型 因为byte是有符号类型,再转成char型时需要进行符号位扩展,如果是正数就在前面不上8个0, 如果是负数就在前面补上8个1。例如11111111(0xff)左边连续补上8个1结果是0xffff。因为char是无符号类型,所以0xffff表示的十进制数是65535。
2. char型转为int型 因为char是无符号类型,转换成int型时进行在前面补上16个0,用十进制表示结果为结果0x0000ffff,对应的十进制数是65535。
3. int型转为byte型 因为int是32位,而byte类型值只占8位,直接截取最后8位。例如-1的补码为0xffffffff,转换为byte型后为0xff,值为-1。
总结:如果最初的数值类型是有符号的,那么就执行符号扩展;如果是char类型,那么不管它要被转换成什么类型,都执行零扩展。还有另外一条规则也需要记住,如果目标类型的长度小于源类型的长度,则直接截取目标类型的长度。例如将int型转换成byte型,直接截取int型的右边8位。 下载地址 ?

时间: 2024-07-30 10:16:56

Java中负数以及类型转换问题的相关文章

关于Java中的基本数据类型转换

Java中的基本类型有四种,其中整型分为byte.short.int.long,浮点型分为float.double,字符型char,布尔型boolean.8种类型的级别由低到高byte->short/char->int->long->float->double. Java中的基本数据类型转换分为隐式类型转换(自动类型转换)和显式类型转换(强制类型转换). 隐式类型转换是将一个较低级别的值或变量赋给一个较高级别的变量,在这种情况下,Java会自动地将较低级别的变量或值转换成与较

Java中的基本类型转换,数据溢出原理

java中的数据类型 java是一种强类型语言,在java中,数据类型主要有两大类,基本数据类型和引用数据类型,不同的数据类型有不同的数据存储方式和分配的内存大小. 基本数据类型中,各数据类型所表示的范围也是不一样的,如下所示: 由于在java中,整数默认是采用int型,浮点数默认采用的是double型进行存储,所以在定义long型和float型数据时,必须在数值后面加'l','L'和'f','F',如: 1 long a = 1000l; 2 long b = 2000L; 3 float c

JavaSE基础(十)--Java中的基本数据类型转换

说基本数据类型转换之前,先了解下 Java 中的 8 种基本数据类型,以及它们的占内存的容量大小和表示的范围,如下图所示. 重新温故了下原始数据类型,现在来解释下它们之间的转换关系. 自动类型转换 自动类型转换是指:数字表示范围小的数据类型可以自动转换成范围大的数据类型. 如: long l = 100; int i = 200; long ll = i; 具体自动转换如如下图所示. 实线表示自动转换时不会造成数据丢失,虚线则可能会出现数据丢失问题. 自动转换也要小心数据溢出问题,看下面的例子.

JAVA中负数转二进制分析

最近在看集合源码,发现ArrayDeque里面用到了大量的&运算,这牵扯到了二进制.突然发现自己对负数的二进制有点模糊了,对此进行了一些支持补充. 首先我们要对原码.反码和补码有个了解: 1.所谓原码就是二进制定点表示法,即最高位为符号位,"0"表示正,"1"表示负,其余位表示数值的大小. 2.反码表示法规定:正数的反码与其原码相同:负数的反码是对其原码逐位取反,但符号位除外. 原码10010= 反码11101 (10010,1为符号码,故为负) (1110

慕课网-安卓工程师初养成-2-9 Java中的自动类型转换

来源:http://www.imooc.com/code/1236 在 Java 程序中,不同的基本数据类型的数据之间经常需要进行相互转换.例如: , 代码中 int 型变量 score1 可以直接为 double 型变量 score2 完成赋值操作,运行结果为: 这种转换称为自动类型转换. 当然自动类型转换是需要满足特定的条件的: 1.  目标类型能与源类型兼容,如 double 型兼容 int 型,但是 char 型不能兼容 int 型 2.  目标类型大于源类型,如 double 类型长度

Java中的自动类型转换

Java里所有的数值型变量可以进行类型转换,这个大家都知道,应该不需要详细解释为什么. 2 在说明自动类型转换之前必须理解这样一个原则“表数范围小的可以向表数范围大的进行自动类型转换” 3 关于java自动类型的转换有这样一个形象的比喻,当一个小的容器的水换到一个大的容器中毫无问题,但是一个大的容器的水换成小的容器则会装不下,就会溢出. 4 下面就是我画出的简要图.

Java中的基本数据类型转换

如果想要做ORM,将数据映射为对象,则基本的数据类型转换是必要的功能,而Java似乎未提供该功能,只有自己下手来完成该功能. 完成该功能的目标如下: 1: 提供基本的数据转换 2: 考虑转换的性能. 下面是我的具体实现: 1: 接口: public static <T> T Cast(Class<T> t, Object value) 2: 依赖:需要依赖与获得数据默认值,因为在很多情况下,如果要转换的数据为null,调用者期望的是返回默认值. 系统自动提供的默认值不能满足我们的需

慕课网-安卓工程师初养成-2-10 Java中的强制类型转换

来源:http://www.imooc.com/code/1241 相信小伙伴们也发现了,尽管自动类型转换是很方便的,但并不能满足所有的编程需要. 例如,当程序中需要将 double 型变量的值赋给一个 int 型变量,该如何实现呢? 显然,这种转换是不会自动进行的!因为 int 型的存储范围比 double 型的小.此时就需要通过强制类型转换来实现了. 语法:( 数据类型 ) 数值 运行结果:  可以看到,通过强制类型转换将 75.8 赋值给 int 型变量后,结果为 75,数值上并未进行四舍

Java中的强制类型转换

例如,当程序中需要将 double 型变量的值赋给一个 int 型变量,该如何实现呢? 显然,这种转换是不会自动进行的!因为 int 型的存储范围比 double 型的小.此时就需要通过强制类型转换来实现了. public class HelloWorld{ public static void main(String[] args) { double heightAvg1=176.2; int heightAvg2=(int)heightAvg1; System.out.println(hei