手机电影网站建设wordpress fpm

当前位置: 首页 > news >正文

手机电影网站建设,wordpress fpm,事业单位可以建设网站吗,大神自己做的下载音乐的网站文章目录整型数据类型无符号数的编码补码编码确定大小的整数类型练习1练习2有符号数和无符号数之间的转换练习C语言中的有符号数与无符号数练习扩展一个数字的位表示练习1练习2截断数字练习关于有符号数与无符号数的建议练习1练习2使用 位编码整数有两种不同的方式#xff1a;… 文章目录整型数据类型无符号数的编码补码编码确定大小的整数类型练习1练习2有符号数和无符号数之间的转换练习C语言中的有符号数与无符号数练习扩展一个数字的位表示练习1练习2截断数字练习关于有符号数与无符号数的建议练习1练习2使用 位编码整数有两种不同的方式只能表示非负数零、正数即无符号数的编码。既能表示非负数也能表示负数即有符号数的编码、补码编码。 下表是一些数学术语用于精确定义和描述计算机如何编码和操作整数。 符号类型含义B2TwB2T_wB2Tw​函数二进制转补码B2UwB2U_wB2Uw​函数二进制转无符号数U2BwU2B_wU2Bw​函数无符号数转二进制U2TwU2T_wU2Tw​函数无符号数转补码T2BwT2B_wT2Bw​函数补码转二进制T2UwT2U_wT2Uw​函数补码转无符号数TMinwTMin_wTMinw​常数最小补码值TMaxwTMax_wTMaxw​常数最大补码值UMaxwUMaxwUMaxw​常数最大无符号数wt^{t}{w}wt​操作补码加法wu^{u}{w}wu​操作无符号数加法∗wt*^{t}{w}∗wt​操作补码乘法∗wu*^{u}{w}∗wu​操作无符号数乘法−wt-^{t}{w}−wt​操作补码取反−wu-^{u}{w}−wu​操作无符号数取反下标w表示整数的位数。 整型数据类型 C语言支持多种整型数据类型——表示有限范围的整数。每种类型都可以用关键字指定大小如char、short、long同时还可以用unsigned表示是无符号的。 无符号数永远是0的。有符号数既能表示负数又能表示非负数在“典型”实现中负数的表示范围比非负数大1不对称。 C语言标准定义了每种数据类型必须能够表示的最小取值范围。对有些数据类型则要求正数和负数的取值范围是对称的。 C/C支持无符号数和有符号数Java只支持有符号数。 无符号数的编码 假设一个整数有w位其编码为[xw−1,xw−2,…,x0][x{w-1}, x_{w-2}, … , x_0][xw−1​,xw−2​,…,x0​]写作位向量x⃗\vec xx。在这个编码中每个位xixixi​取值为0或1。 原理无符号数的编码定义。 对向量x⃗[xw−1,xw−2,…,x0]\vec x [x{w-1}, x_{w-2}, … , x_0]x[xw−1​,xw−2​,…,x0​]有 B2Uw(x⃗)˙∑i0w−1xi2i\begin{align} B2Uw(\vec x) .\displaystyle\sum{i0}^{w-1}x_i2^i \end{align} B2Uw​(x)˙i0∑w−1​xi​2i​​ ˙.˙表示左边被定义为等于右边。 函数 B2Uw(x⃗)B2U_w(\vec x)B2Uw​(x)将一个长度为w的0、1串映射为非负整数函数的返回值就是该编码的无符号数值。 x⃗\vec xx所能表示的最小值为[0, 0, …, 0]w个0该编码对应的无符号数值为0最大值是[1, 1, …, 1]w个1该编码对应的无符号数值为 UMaxw˙B2Uw([1,1,…,1])∑i0iw−12i2w−1UMax_w . B2Uw([1, 1, …, 1]) \displaystyle\sum{i0}^{iw-1}2^{i} 2^w - 1UMaxw​˙B2Uw​([1,1,…,1])i0∑iw−1​2i2w−1。 因此函数B2UwB2U_wB2Uw​能够被定义为一个映射{0,1}w→{0,1,2,…,2w−1}{0, 1}^w \to {0, 1, 2, …, 2^{w}-1}{0,1}w→{0,1,2,…,2w−1}。 原理无符号数编码是唯一的。 函数B2UwB2U_wB2Uw​是一个双射。 对函数 B2Uw(x⃗)B2U_w(\vec x)B2Uw​(x)而言给定一个位向量x⃗\vec xx有唯一对应的无符号数值。 对函数 U2Bw(y)U2Bw(y)U2Bw​(y)而言给定一个无符号数值yyy有唯一对应的位向量x⃗\vec xx。 补码编码 最常见的有符号数的计算机表示方法是补码编码。在这个定义中将最高有效位解释为负权。 原理补码编码定义。 对向量x⃗[xw−1,xw−2,…,x0]\vec x [x{w-1}, x_{w-2}, … , x_0]x[xw−1​,xw−2​,…,x0​]有 B2Tw(x⃗)˙−xw−12w−1∑i0w−2xi2i\begin{align} B2Tw(\vec x) .-x{w-1}2^{w-1} \displaystyle\sum_{i0}^{w-2}xi2^i \end{align} B2Tw​(x)˙−xw−1​2w−1i0∑w−2​xi​2i​​ 最高有效位xw−1x{w-1}xw−1​也称为符号位它的权重为−2w−1-2^{w-1}−2w−1。xw−1x_{w-1}xw−1​为1时该值是负数为0时该值是非负数。 x⃗\vec xx所能表示的最小值为[1, 0, …, 0]值为TMinw˙−2w−1TMin_w.-2^{w-1}TMinw​˙−2w−1最大值为[0, 1, …, 1]值为TMaxw2w−1−1TMax_w2^{w-1}-1TMaxw​2w−1−1。 因此函数B2TwB2T_wB2Tw​能够被定义为一个映射{0,1}w→{−2w−1,−2w−11,…,2w−1−2,2w−1−1}{0, 1}^w \to {-2^{w-1}, -2^{w-1} 1, …, 2^{w-1}-2, 2^{w-1}-1}{0,1}w→{−2w−1,−2w−11,…,2w−1−2,2w−1−1}。 原理补码编码是唯一的。 函数B2TwB2T_wB2Tw​是一个双射。 对函数 B2Tw(x⃗)B2T_w(\vec x)B2Tw​(x)而言给定一个位向量x⃗\vec xx有唯一对应的有符号数值。 对函数 T2Bw(y)T2B_w(y)T2Bw​(y)而言给定一个有符号数值yyy有唯一对应的位向量x⃗\vec xx。 相同的位向量 x⃗\vec xx 在不同的语境下有不同的含义。 如果 x⃗\vec xx 是[1, 1, …, 1]的串无符号数值语境下表示UMax有符号数值语境下表示-1。 如果 x⃗\vec xx 是[1, 0, …, 0]的串无符号数值下表示正数 2w−12^{w-1}2w−1有符号数值下表示负数 −2w−1-2^{w-1}−2w−1 最高位为0的情况下无符号数值和有符号数值相等。 C语言标准并没有要求采用补码形式表示有符号数但几乎所有的机器都是这么做的。如果程序员希望代码具有最大的可移植性那么就该假定有符号数是采用补码编码的。 补码对于非负数x用2w−x2^w - x2w−x的值表示-x。 反码对于非负数x用2w−1−x2^w - 1 - x2w−1−x的值表示-x。 确定大小的整数类型 ISO C99标准定义了确定大小的整数类型。如int32_t和uint64_t。无论在哪台机器上它们都分别表示32位的有符号数和64位的无符号数。标准也定义了诸如INT32_MAX、INT32_MIN、UINT64_MAX这样的宏表示对应整数类型值的范围。标准也定义了诸如PRId32、PRIu64这样的宏表示格式化打印相应的整型变量时的宽度。 相比于C/CJava标准定义更明确一些仅支持有符号数、整型的表示范围确定、采用补码编码。 练习1 位向量 x⃗\vec xx 的长度w 4填写下表。 位向量 xB2UB2T十六进制二进制0xE[1110]14-20x0[0000]000x5[0101]550x8[1000]8-80xD[1101]13-30xF[1111]15-1 练习2 将下列使用32位补码表示的16进制数转换成等价的10进制数。 0x2e0 736-0x58 -880x28 40-0x30 -480x78 1200x88 1360x1f8 5040xc0 192-0x48 -72 有符号数和无符号数之间的转换 相同位宽的有符号数和无符号数之间强制类型转换的结果是底层位值不变但改变了解释这些位的方式。比如把short类型的-12345转换成unsigned short会得到53191事实上这两个数的底层位值是一模一样的。再比如把UINT_MAX强转为有符号数会得到-1UINT_MAX和-1的底层位值都是[1, 1, …, 1]。 因此我们可以通过分析二进制表示完成有符号数和无符号数之间的转换。 原理从有符号数转无符号数。 对于位宽为w的有符号数xxx二进制表示为位向量 x⃗\vec xx满足TMinwxTMaxwTMin_w x TMax_wTMinw​xTMaxw​有 T2Uw(x)˙B2Uw(T2Bw(x))xxw−12w{x2w,x0x,x0\begin{align} T2U_w(x).B2U_w(T2Bw(x)) xx{w-1}2^w \begin{cases} x2^w, \quad x0 \ x, \quad x0 \end{cases} \end{align} T2Uw​(x)˙B2Uw​(T2Bw​(x))xxw−1​2w{x2w,x,​x0x0​​​ 有符号数的最高位权值是−2w−1-2^{w-1}−2w−1无符号数的最高位权值是2w−12^{w-1}2w−1两者相差2w2^{w}2w。所以当最高位为1x0x0x0时无符号数值比有符号数值大2w2^{w}2w。 原理从无符号数转有符号数。 对于位宽为w的无符号数xxx二进制表示为位向量 x⃗\vec xx满足0xUMaxw0x UMax_w0xUMaxw​有 U2Tw(x)˙B2Tw(U2Bw(x))x−xw−12w{x,xTMaxwx−2w,xTMaxw\begin{align} U2T_w(x).B2T_w(U2Bw(x))x-x{w-1}2^w \begin{cases} x, \quad xTMax_w \ x-2^w, \quad xTMax_w \end{cases} \end{align} U2Tw​(x)˙B2Tw​(U2Bw​(x))x−xw−1​2w{x,x−2w,​xTMaxw​xTMaxw​​​​ 当最高位为1xTMaxwxTMax_wxTMaxw​时有符号数比无符号数小2w2^w2w。 练习 补充下面的表格。 xxxT2U4(x)T2U_4(x)T2U4​(x)-88-313-214-1150055 C语言中的有符号数与无符号数 在C语言中声明一个常量时默认是有符号的如123、0xAB。要创建无符号常量需要加上后缀字符u或U如123u、0xABu。 可以显示转换如 int i; unsigned int u;i (int)u; u (unsigned int)i;可以隐式转换如 int i; unsigned int u;i u; u i;或 int i; unsigned int u;printf(%u\n, i); printf(%d\n, u);当执行一个运算时如果它的一个运算数是有符号的另一个运算数是无符号的那么C语言会隐式地将有符号参数转换为无符号数再进行无符号数之间的运算。 练习 假设在采取补码运算的32位机器上执行以下运算填写运算的类型和结果。 表达式类型求值-2147483647-1 2147483648U无符号1-2147483647-1 2147483647有符号1-2147483647-1U 2147483647无符号0-2147483647-1 -2147483647有符号1-2147483647-1U -2147483647无符号1 扩展一个数字的位表示 要将一个无符号整数转换为一个更大的数据类型只需要简单地在高位加0这种运算被称为无符号数的零扩展。 要将一个有符号整数转换为一个更大地数据类型需要在高位加符号位这种运算被称为补码的符号扩展。 当数据扩展和有无符号转换同时出现时C标准要求先扩展、后进行有无符号转换。 short sx -12345; unsigned int uy sx; // 等价于unsigned int uy (unsigned int)(int)sx; // uy的十六进制表示为0xFFFFCFC7如果先做符号转换、再扩展那uy的十六进制表示为0x0000CFC7就无法正确表示原值sx的符号位。 练习1 下面各个补码对应的有符号数值是多少 [1011] −232120−5-2^32^12^0-5−232120−5[11011] −24232120−5-2^42^32^12^0-5−24232120−5[111011] −2524232120−5-2^52^42^32^12^0-5−2524232120−5 后两个有符号数分别是第一个有符号数符号扩展1位和2位的结果。符号扩展不会改变补码表示的数值大小。 练习2 考虑下面的C函数 int fun1(unsigned word) {return (int)((word 24) 24); }int fun2(unsigned word) {return ((int)word 24) 24; }填写下表。 wwwfun1(w)fun1(w)fun1(w)fun2(w)fun2(w)fun2(w)0x000000760x000000760x000000760x876543210x000000210x000000210x000000C90x000000C90xFFFFFFC90xEDCBA9870x000000870xFFFFFF87 截断数字 当将一个w位的数截断为一个k位的数时会丢弃高w-k位并对低k位做新的解释。截断一个数可能会改变它的值即溢出。 练习 将一个4位数值截断为一个3位数值填写下表。 十六进制无符号十进制补码十进制原始值截断值原始值截断值原始值截断值0x00x000000x20x222220x90x191-710xB0x3113-530xF0x7157-1-1 关于有符号数与无符号数的建议 整数的扩展和截断、有符号数和无符号数之间的隐式转换会导致程序错误或漏洞。而这些不符合预期的行为有时很难被程序员发现。避免这些错误的方法有 整数运算时统一符号。如果涉及到整数类型的变化使用强制转换代替隐式转换方便程序员发现问题。 练习1 考虑下面的代码当length等于0时预期结果是0.0。但实际上运行时会造成一个内存错误。为什么该如何修改代码 float sum_elements(float a[], unsigned length) {float result 0;for (int i 0; i length - 1; i) {result a[i];}return result; }length是无符号数i是有符号数程序执行i length - 1时程序会按无符号数执行该运算。 当length 0时在无符号数的语境下length - 1等于UINT_MAXi的值永远小于UINT_MAX所以程序会访问未知内存导致运行时错误。 解决办法是 把length的类型改为int。当length 0时在有符号数的语境下length - 1等于-1i的值是0程序立即返回0.0。把i length - 1改为i length。 练习2 下面的代码用来判断一个字符串是否比另一个更长。在头文件stdio.h中size_t是无符号整型。 // 库函数 size_t strlen(const char *s);// 用户代码 int strlonger(char *s, char *t) {return strlen(s) - strlen(t) 0; }在什么情况下这个函数会产生不正确的结果为什么 如果strlen(s)小于strlen(t)strlen(s) - strlen(t)的预期结果应该是个负数 strlen(s) - strlen(t) 0的预期结果应该是0。 但strlen(s)和strlen(t)的返回值都是无符号数strlen(s) - strlen(t)的结果也是无符号数无符号数一定是0的。因此程序会返回1而不是0和预期不符。如何修改代码使其正确。 把return strlen(s) - strlen(t) 0;改为return strlen(s) strlen(t);