四、简单数据的描述 一一基本数据类型和表达式 (深入话题
四、 简单数据的描述 −−基本数据类型和表达式 (深入话题)
主要内容 整数和实数的机内表示 位操作 ■操作数的类型转换 短路求值 带副作用的操作符的表达式计算 左值表达式和右值表达式
主要内容 ◼ 整数和实数的机内表示 ◼ 位操作 ◼ 操作数的类型转换 ◼ 短路求值 ◼ 带副作用的操作符的表达式计算 ◼ 左值表达式和右值表达式
inti=2147483647: int j=10; cout<<i+j;/结果:-2147483639,为什么? double d1=0.1,d2=0.2,d3=0.3; if(d1+d2==d3) cout<≤"OK";/结果没输出!为什么?
int i=2147483647; int j=10; cout << i+j; //结果:-2147483639,为什么? double d1=0.1,d2=0.2,d3=0.3; if (d1+d2 == d3) cout << "OK"; //结果没输出!为什么?
整数的机内表示 原码表示 。用一个二进制位表示符号(0表示正;1表示负), 其它位为二进制表示的绝对值 例如,如果用一个字节存储整数的原码,则 12表示为00001100:-12表示为10001100 。对于由个二进位构成的原码,它能表示的整数范 围是: -(2n-1-1)~2n-1-1,其中有两个零:00..0和10..0
◼ 原码表示 • 用一个二进制位表示符号(0表示正;1表示负), 其它位为二进制表示的绝对值。 • 例如,如果用一个字节存储整数的原码,则 ◼ 12表示为 00001100;-12表示为10001100 • 对于由n个二进位构成的原码,它能表示的整数范 围是: ◼ -(2n-1-1)~2n-1-1,其中有两个零:00...0和10...0。 整数的机内表示
■2的补码表示 。正整数的补码为它的二进制原码表示;负整数的补 码为把相应正整数的各个二进制位取反后得到的值 加1。 例如:如果用一个字节存储整数的补码,则 12表示为: 00001100:-12表示为:11110100 对于由个二进位构成的补码,它能表示的整数范 围是: -2n-1~2n-1-1,其中,00..0表示零,10..0表示-2n-1
◼ 2的补码表示 • 正整数的补码为它的二进制原码表示;负整数的补 码为把相应正整数的各个二进制位取反后得到的值 加1。 • 例如:如果用一个字节存储整数的补码,则 ◼ 12表示为: 00001100;-12表示为:11110100 • 对于由n个二进位构成的补码,它能表示的整数范 围是: ◼ -2n-1~2n-1-1,其中,00...0表示零,10...0表示-2n-1
CPU的整数运算指令一般是针对补码表示来设 计的! 用补码表示整型数便于加、减运算,特别地, 减法可以转换成加法来做。例如: 5加-2 2减8 =2加-8 00000101 (⑤的补码) 00000010 (2的补码》 十 11111110 (-2的补码) +11111000 (-8的补码) 100000011 (3的补码, 11111010 (-6的补码) 最高进位舍去) 早期计算机的CPU中运算器只是一个加法器!
◼ CPU的整数运算指令一般是针对补码表示来设 计的! ◼ 用补码表示整型数便于加、减运算,特别地, 减法可以转换成加法来做。例如: 5 加 -2 00000101 (5的补码) + 11111110 (-2的补码) 100000011 (3的补码, 最高进位舍去) 2 减 8 = 2 加 -8 00000010 (2的补码) + 11111000 (-8的补码) 11111010 (-6的补码) 早期计算机的CPU中运算器只是一个加法器!
inti=2147483647. int j=10; c0ut<<i+j;/结果:-2147483639,为什么? (2147483647)10=(01...1)2 (10)10=(0...01010)2 (-2147483639)10=(10...01001)2 ⅰ+j的结果超出了正整数的范围!
int i=2147483647; int j=10; cout << i+j; //结果:-2147483639,为什么? (2147483647)10 = (01........1)2 (10)10 = (0.....01010)2 (-2147483639)10 = (10....01001)2 • i+j的结果超出了正整数的范围!
实数的机内表示 在计算机内部,实数一般采用基于科学记数法的二进制小数 形式来表示: ±a×2b a是一个二进制小数,称为尾数(Mantissa),b是一个二进制整 数,称为阶码或指数(Exponent) 计算机内部只存储符号以及a和b,并且a和b具有固定长度。 在存储实数前首先需要对其进行规格化,即把尾数ā调整为 1.xxx..形式,其中的整数位“1"和小数点不存储。 例如,对于十进制实数12.5, 规格化: (12.5)10=(1100.1)2=(1.1001)2×23 存储的是:0(符号)、1001(尾数)和3(指数,存储时将 转化成某种二进制形式)两个部分(参见教材附录B)
实数的机内表示 ◼ 在计算机内部,实数一般采用基于科学记数法的二进制小数 形式来表示: ±a×2b • a是一个二进制小数,称为尾数(Mantissa),b是一个二进制整 数,称为阶码或指数(Exponent) 。 • 计算机内部只存储符号以及a和b,并且a和b具有固定长度。 • 在存储实数前首先需要对其进行规格化,即把尾数a调整为 1.xxx...形式,其中的整数位“1”和小数点不存储。 ◼ 例如,对于十进制实数12.5, • 规格化: (12.5)10 = (1100.1)2 = (1.1001)2×2 3 • 存储的是:0(符号)、1001(尾数)和3(指数,存储时将 转化成某种二进制形式)两个部分(参见教材附录B)
在实数的这种表示中,小数点的位置并不 表示它的实际位置,其真正位置是在“浮 动”着的,要由尾数和指数共同来决定, 因此,在计算机中实数常常又称为浮点数 (float-point number) CPU的实数运算指令一般是针对实数的浮 点表示来设计的!
◼ 在实数的这种表示中,小数点的位置并不 表示它的实际位置,其真正位置是在“浮 动”着的,要由尾数和指数共同来决定, 因此,在计算机中实数常常又称为浮点数 (float-point number)。 ◼ CPU的实数运算指令一般是针对实数的浮 点表示来设计的!
double d1=0.1,d2=0.2,d3=0.3 if(d1+d2==d3) cout≤<"OK",/结果没输出!为什么? (0.1)10=(0.000110011..)2=(1.10011001..)2×24 =(1.1001100110011001100110011001100110011001100110011010),×24 (0.2)10元. 截断时有 (0.3)10.… 舍入! 。0.1、0.2、0.3在计算机中存储的是它们的近似值!
double d1=0.1,d2=0.2,d3=0.3; if (d1+d2 == d3) cout << "OK"; //结果没输出!为什么? (0.1)10=(0.000110011...)2 =(1.10011001...)2×2 -4 =(1.1001100110011001100110011001100110011001100110011010)2×2 -4 (0.2)10=... (0.3)10=... • 0.1、0.2、0.3在计算机中存储的是它们的近似值! 截断时有 舍入!