原码、反码和补码
在计算机内,有符号数有三种表示法:原码,反码,补码。计算机中,所有数据的运算都是采用补码进行的。
原码:二进制定点表示法,即最高位为符号位。0表示正,1表示负,其余位表示数值的大小。
反码:正数的反码与其原码相同。负数的反码是对其原码逐位取反,但符号位除外。
补码:正数的补码与其原码相同。负数的补码是在其反码的末位+1。
浮点数
浮点数:浮点数是属于有理数中某特定子集的数的数字表示,在计算机中用以近似表示任意某个实数。具体的说,这个实数由一个整数或定点数(即尾数)乘以某个基数(计算机中通常是2)的整数次幂得到,这种表示方法类似于基数为10的科学计数法。
一个浮点数a由两个数m和e来表示:a = m × b^e^。(计算机中b一般为2) 尾数就是小数 二进制的小数点和十进制的小数点是不同的。二进制小数点后是2的负幂,十进制是10的负幂。
float类型数字在计算机中用4个字节存储。遵循IEEE-754格式标准:一个浮点数有2部分组成:底数m和指数e
底数部分m: 使用二进制数来表示此浮点数的实际值
指数部分e: 占用8bit的二进制数,可表示数值范围为0-255
但是指数可正可负,所以,IEEE规定,此处算出的次方必须减去127才是真正的指数。所以,float类型的指数可从-126到128
底数部分实际是占用24bit的一个值,但是最高位始终为1,所以,最高位省去不存储,在存储中占23bit
格式:
SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM
S表示浮点数正负
E指数加上127后的值得二进制数据,指数位决定了大小范围
M底数,尾数位决定了计算精度
举例:
17.625在内存中的存储
首先要把17.625换算成二进制:10001.101
整数部分,除以2,直到商为0,余数反转。
小数部分,乘以2,直到乘位0,进位顺序取。
在将10001.101右移,直到小数点前只剩1位: 1.0001101 * 2^4 因为右移动了四位
这个时候,我们的底数和指数就出来了
底数:因为小数点前必为1,所以IEEE规定只记录小数点后的就好。所以,此处的底数为:0001101
指数:实际为4,必须加上127(转出的时候,减去127),所以为131。也就是10000011
符号部分是正数,所以是0
综上所述,17.625在内存中的存储格式是:
01000001 10001101 00000000 00000000
float 符号位1bit 指数位e 8bit 尾数位m 23bit
double 符号位1bit 指数位e 11bit 尾数位m 52bit
boolean占几个字节
虽然boolean表现出非0即1的“位”特性,但是存储空间的基本计量单位是字节,不是位。所以boolean至少占一个字节。
JVM规范中,boolean变量作为int处理,也就是4字节(声明一个基本变量类型时,占4个字节);boolean数组当做byte数组处理(声明一个数组类型时,数组中的每个元素占1个字节)
运算符的优先级
优先级 | 描述 | 运算符 |
---|---|---|
1 | 括号 | ()、[] |
2 | 正负号 | +、- |
3 | 自增自减,非 | ++、–、! |
4 | 乘除,取余 | *、/、% |
5 | 加减 | +、- |
6 | 移位运算 | <<、>>、>>> |
7 | 大小关系 | >、>=、<、<= |
8 | 相等关系 | ==、!= |
9 | 按位与 | & |
10 | 按位异或 | ^ |
11 | 按位或 | | |
12 | 逻辑与 | && |
13 | 逻辑或 | || |
14 | 条件运算 | ?: |
15 | 赋值运算 | =、+=、-=、*=、/=、%= |
16 | 位赋值运算 | &=、|=、<<=、>>=、>>>= |
如果在程序中,要改变运算顺序,可以使用()括起来
编码问题
java语言使用的是Unicode编码。
一般软件中的ANSI指的是对应当前系统 locale 的遗留(legacy)编码。
建议用 Notepad++ 等正常的专业文本编辑器保存为不带 BOM 的 UTF-8。另外,如果文本中所有字符都在 ASCII 范围内,那么其实,记事本保存的所谓的「ANSI」文件,和 ASCII 或无 BOM 的 UTF-8 是一样的。
ASCII码表
ASCII码规定最高位必须为0,因此只能有128个,即0~127。
于是需要Unicode(统一码,万国码,单一码)这个东西,就是要把地球上所有的语言的符号,都用统一的字符集来表示,一个编码真正做到了唯一,在表示Unicode字符时,通常会用“U+”然后紧跟着一组十六进制的数字来表示。
UTF-8是针对Unicode的一种可变长度字符编码,可以用来表示Unicode标准中的任何字符,而且编码中的第一个字节与ASCII相容。UTF-8使用一至四个字节为每个字符进行编码,汉字一般采用3个字节。
中文网站不需要其他国家的文字出现,用UTF-8进行编码,大多数占用3个字节甚至更多,会造成存储浪费,所以采用一套GB系列的编码,最常用的是GBK。GBK编码英文采用单字节编码,完全兼容ASCII码表,汉字采用2个字节进行编码,范围为0x8140到0xFEFE(剔除xx7F,因为对应的ASCII码表是DEL,意味着要向后删除一个字符)
Unicode定义一个特殊字符�,对应编码为0xFFFD。假如A支持一个特殊字符,但B不支持,在B中就会用�代替。这个字符用UTF-8编码后,十六进制表示为0xEF 0XBF 0XBD,如果连续出现两个符号,即为0xEF 0XBF 0XBD 0xEF 0XBF 0XBD,再转换成GBK码(2个字节一个字符)就成了锟(0xEFBF),斤(0xBDEF),拷(0xBFBD)。出现锟斤拷的原因就是UTF-8转码GBK时出现了问题,至少需要两个字符出现乱码才会出现锟斤拷。
Unicode编码:指的是带有 BOM 的小端序 UTF-16(BOM(byte order mark)也是Unicode标准的一部分,有它特定的适用范围。通常BOM是用来标示Unicode纯文本字节流的,用来提供一种方便的方法让文本处理程序识别读入的.txt文件是哪个Unicode编码(UTF-8,UTF-16BE,UTF-16LE),Linux系统不会识别BOM,直接读取;而windows会先识别,从而会使一些代码加载出问题)
UTF-8编码:指的是带 BOM 的 UTF-8。(对于微软而言)linux系统的UTF-8是不带BOM的,因为他要运行老版本。而windows系统之前是不带BOM的,但是为了考虑兼容性问题,所以以后的UTF-8编码都是带BOM的。(这里推荐使用不带的)
java中的参数传递问题
基本类型:形式参数的改变对实际参数没有影响。(值传递)
引用类型:形式参数的改变直接影响实际参数。(地址值传递)