zoukankan      html  css  js  c++  java
  • [CSAPP笔记]Binary , Unsigned , Signed 之间的相互装换

    LaTex+MarkDown+Pandoc组合套件写博客的处女作,试试效果。各自的分工为:Latex下编辑公式,在Sublime Text 2下使用Markdown排版,最后用Pandoc导出。

    摘要

    本文主要讲解 Binary , Unsigned , Signed 三种数据中任意两者之间的转换。下面是文中的一些约定写法。

    • 转换名称
      • B2Uw(x) : 将位数为w的二进制数 binary 转换为无符号数Unsigned
      • B2Tw(x) : 将位数为w的二进制数 binary 转换为补码 Two's complement
    • 二进制数的表示 (x) : 用一个向量表示,x = ( x1 , x2 , ... , xw)

    1. U2Bw(x)

    直接用辗转相除法即可。

    2. S2Bw(x)

    正数直接装换,然后左边添加0 ; 负数先将其绝对值装换成二进制数,再对低w-1位取反,最高位添加1,用公式表示即为: 下面以三位的三进制数来说明有符数的补码表示

    • 3 = 011
    • 2 = 010
    • 1 = 001
    • 0 = 000
    • -1 = 111
    • -2 = 110
    • -3 = 101
    • -4 = 100

    3. B2Uw(x)

    egin{equation} B2U_wleft( overrightarrow{x} ight) doteq sum_{i=0}^{w-1} x_i 2^i label{B2U} end{equation}

    4. B2Tw(x)

    egin{equation}B2T_wleft( overrightarrow{x} ight) doteq -x_{w-1} 2^{w-1} + sum_{i=0}^{w-2} x_i 2^i label{B2T} end{equation}

    5. T2Uw(x)

    函数 T2Uw(x) 定义为 T2Uw(x) = T2Bw(B2Uw(x)) 。这个函数输入的是一个 -2(w-1) ~ 2(w-1)-1 之间的数,而输出的无符数也即为该有符数的补码表示。
    对于位模式 下的有符二进制数 $overrightarrow{x}$ ,对比式($ ef{B2U}$) 和式($ ef{B2T}$) , 计算两者之差,我们就可以得到:$ B2U_wleft( overrightarrow{x} ight) - B2T_wleft( overrightarrow{x} ight) = x_{w-1}  left( 2^{w-1} - left( -2^{w-1} ight) ight)  =  x_{w-1} 2^w $ 。这样就得到了:$B2U_wleft( overrightarrow{x} ight) = x_{w-1} 2^w + B2T_wleft( overrightarrow{x} ight)$。若令 $overrightarrow{x} = T2B_w left( x ight) $ ,则其反函数为 $ x = B2T_w left( overrightarrow{x} ight) $。  由前面三式以及T → B → U变换的传递性,可得:

    egin{equation} B2U_wleft( T2B_w left( x ight) ight) = T2U_w left( x ight) = x_{w-1} 2^w + x label{T2U} end{equation}
    这个关系对于理解“有符数变换得到的无符数也即补码”很有用。 

    $$ T2U_w left( x ight)=left{
    egin{aligned}
    & x+2^w, & x<0,x_{w-1}=1 \
    & x, & x geq 0,x_{w-1}=0 
    end{aligned}
    ight.$$


    下图说明了 T2U 的转换行为:对于非负数(x ≥ 0), T2U 保留原值 :

    图1. 从补码到无符号数的转换。函数 将负数转换为大的正数

    6. U2Tw(x)

    函数 U2Tw(x) 定义为 U2Tw(x) = B2Tw(U2Bw(x)) 。这个函数输入的是一个 0 ~ 2(w-1)-1 之间的数,输出则为一个 -2w ~ 2(w-1) 之间的数。
    上一节我们已经得到,对于负数(x < 0),T2U 被装换为一个大于2w − 1的正数。
    反过来,我们再来推导无符号数 u 和与之对应的有符号数 U2Tw(u)之间的关系。 利用上一节的结论, $B2T_wleft( overrightarrow{u} ight) = B2U_wleft( overrightarrow{u} ight) - u_{w-1} 2^w$ 。若令 $overrightarrow{u} = U2B_w left( u ight)$,则其反函数为 $u = B2U_w left( overrightarrow{x} ight)$ 。由前面三式以及 T → B → U 变换的传递性,可得:

    egin{equation}B2T_wleft( U2B_w left( u ight) ight) = U2T_w left( u ight) = u - u_{w-1} 2^w label{U2T} end{equation}

    在 u 原始的无符号表示法中,最高位uw − 1决定了 u 是否大于或等于 2w − 1, 无符数 u 到有符数的装换分段表示为:

    $$ U2T_w left( u ight)=left{
    egin{aligned}
    & u, & u<2^{w-1},x_{w-1}=0 \
    & u-2^w, & x leq 0,x_{w-1}=1
    end{aligned}
    ight.$$

    下图说明了 U2T 转换行为:对于小的数(u < 2w − 1), U2T 保留原值 ; 对于大的数(u ≥ 2w − 1),U2T 被装换为一个负数:

    图2.从无符号数到补码的转换。函数U2T 把大于 的数字转换为负值

    练习

    1.如下函数,在32bit系统中,求问foo(2^31-3)的值是:

    int foo(int x) { 
        return x&-x; 
    }

    A.0  B.1  C.2   D.4

    解答:

    • (1).运算符号的优先级,减号 '-' 高于异或 '^' 。所以 231-3=2(31-3)=2^28=30
    • (2).32位机器中int整型的位数的为 w=32 ,位运算 x 取反,其实为 0xFFFFFFFF-x ,而不是用 232 减去。
    • (3).本题中,x=30=0x1E ,依据 T2Uw 可得 -x=0xFFFFE2,所以_x&-x=2_,本题选B
    • (4)有么有更简单方法。

    y = x & (-x)
    That does a bitwise AND between the variable x and its negation, and assigns the result to the variable y. If your system uses two's complement signed arithmetic , then what that manages to get you is the greatest power of 2 that is a factor of x. So, if x is 24, y gets assigned 8, and if x is 12, y gets assigned 4, and if x is 99, y becomes 1. To understand why it does that, you need to understand binary, and two's complement. Look them up on wikipedia.

    • 用 15, 16 ,48 三个数验证结论
      • x=15=0x0F , -x=-15=232-0x0F=0xFFFFFFF1 , 所以 x&-x=0xF1 & 0x0F = 1 ;
      • x=16=0x10 , -x=-16=232-0x10=0xFFFFFF0 , 所以 x&-x=0xF0 & 0x10 = 16
      • x=48=0x30 , -x=-48=232-0x30=0xFFFFFD0 , 所以 x&-x=0xD0 & 0x30 = 16
    • 总结起来就是, x&-x 得到的是数x的最低一位的非0比特数。

    reference

    1. CASPP

    2. yahoo关于y = x & (-x)问题的解答

  • 相关阅读:
    Android在layout xml中使用include完成静态加载
    ImageSwitch图像切换控件
    合并石子大总结
    子矩阵(暴搜(全排列)+DP)
    回路(一笔画问题)
    道路重建(记忆化搜索+贪心)
    【NOIP2013 普及组】车站分级
    UML的基本关联
    Matlab画图-非常具体,非常全面
    面向对象程序设计与面向过程程序设计解析
  • 原文地址:https://www.cnblogs.com/ouxiaogu/p/3338537.html
Copyright © 2011-2022 走看看