• 2_77 开始


    ---恢复内容开始---

    前面的空缺是我忘了保存 ##2.77## 使用位移运算和+- 实现乘法运算 A k=17 C=x<<4+x B k=-7 C=x-(x<<3) C k=60 C=x<<6-x<<2 D k=-112 就不做了 ##2.78## 写出具有如下原型的函数 ``` int divide_power2(int x,int k){ int w=sizeof(int)*8; int mask=x>>w-1; int bios=(1<>k; } ``` 使用负数掩码添加bios的技巧 ##2.79## 计算函数 ``` int mul3div4(int x){ x=x<<1+x; return divide_power2(x,2); } ``` //这个版本只需要先乘然后除就可以了 ##2.80## 新的版本不要求溢出 ``` int threefourths(int x){ int b1=divide_power2(x,1); int b2=divide_power2(x,2); return b1+b2; } //这个版本可以改进的,所有的掩码应该是一样的,我就不写了 ``` ##2.81## A. 1[w-n]0[n]: ~((1<-y 对于大部分正负合理的数是对的 ,但是极端数当 x等于 INT_MIN时不对 B (((x+y)<<4)+y-x)==17*y+15*x 只是加减构成了阿贝尔群 , 这样的等是没有问题 C ~x+~y+1= ~(x+y) 这个因该是对的 有这个式子 -x=~x+1 恒成立 D 对的 (ux-uy)==-(unsigned)(y-x) E ((x>>2)<<2)<=x 因该是对的 最后的两位被归零了 其余的位不变

    2.83##

    A. 令x为无穷序列表示的值,可以得到x*2^k = Y + x。 所以 x = Y/(2^k - 1)。 B. (a)1/7, (b)9/15 = 3/5, (c)7/63 = 1/9
    表示无穷的方法

    2.84##

    通过符号位来判断float的大小这种方法是有非常好的性质,因为浮点数的自然顺序就是如此
    还是漏掉了一种方法。
    有四种不同的情况
    一正一负
    都是零
    同正
    同负
    ((ux<<1)0 && (uy<<1)0) || (!sx && sy) || (!sx && !sy && ux >= uy) || (sx && sy && ux <= uy);

    2.85##

    有k位指数 n位小数
    写出阶码E,尾数M,小数f,和值V得公式

    数7.0###

    E =10011 (共k位)
    f =11000共n位
    尾数

    够被准确描述的最大奇整数###

    小数f 1111(全一 共N位 )
    阶码 10011 (值是n) 2^(n-1) 这么大
    值因该是
    11111111 有n+1个 1
    这个值是 2^n -1

    最小的规格化数的倒数###

    最小的规格化数
    阶码
    00000001 -2^(k-1) +2// 1-bios bios=2^(k-1)-1
    小数
    0000000 全零代表 1
    值 2{-2(k-1)+2}

    取导之后是
    2^{ 2^(k-1) -2}
    阶码是 11101 只有第1位是0 // 值应该是 2^k-1 -2 + bios
    2^(k-1)
    尾数是全零表示1

    阶数的符号表示不是补码表示,进行计算的时候要带上bios
    2^k-1 -1 这个是bios 换句话讲阶数等于0是这样的 01111111 大于零的阶数首位必定是1

    2.86##

    精度扩展的问题
    80位字节下浮点数的一些特值
    1 个符号位
    15个阶码位
    1个整数位 规格化数位1 非规格化数值为零
    63个小数位
    最小的 正非规格化数

    2^( -2^(14) +###2### ) * 2^(-63)
    //非规格化数阶数为1- bios 为了平滑的过渡
    3.645*10^(-4951)
    最小的正规格化数
    2(-214 +2 )
    最大的规格化数
    (2-2(-63))*2{2 ^(14))}

    2.87##

    在 一个符号位 五个阶码位 10个尾数位 时填表

    描述 Hex M E V D
    -0 8000 0 0 -0 *
    最小的大于2的值 4001 0000000001 10000 2 +2^-9 *
    512 6000 0000000000 11000 512 512.0

    ---恢复内容结束---

    前面的空缺是我忘了保存

    2.77##

    使用位移运算和+- 实现乘法运算
    A k=17 C=x<<4+x
    B k=-7 C=x-(x<<3)
    C k=60 C=x<<6-x<<2
    D k=-112 就不做了

    2.78##

    写出具有如下原型的函数

    int divide_power2(int x,int k){
    	int w=sizeof(int)*8;
    	int mask=x>>w-1;
    	int bios=(1<<k)-1;
    //	printf("%d",bios);
    	return(x+bios&mask)>>k;
    }
    

    使用负数掩码添加bios的技巧

    2.79##

    计算函数

    int mul3div4(int x){
    	x=x<<1+x;
    	return divide_power2(x,2);
    }
    

    //这个版本只需要先乘然后除就可以了

    2.80##

    新的版本不要求溢出

    int threefourths(int x){
    	int b1=divide_power2(x,1);
    	int b2=divide_power2(x,2);
    	return b1+b2;
    }
    //这个版本可以改进的,所有的掩码应该是一样的,我就不写了
    

    2.81##

    A. 1[w-n]0[n]: ~((1<<n) - 1)
    B. 0[w-n-m]1[n]0[m]: ((1<<n) - 1) << m

    2.82##

    A x<y == -x>-y
    对于大部分正负合理的数是对的 ,但是极端数当 x等于 INT_MIN时不对
    B (((x+y)<<4)+y-x)17y+15x 只是加减构成了阿贝尔群 , 这样的等是没有问题
    C x+y+1= ~(x+y) 这个因该是对的 有这个式子 -x=~x+1 恒成立
    D 对的 (ux-uy)
    -(unsigned)(y-x)
    E ((x>>2)<<2)<=x 因该是对的 最后的两位被归零了 其余的位不变

    2.83##

    A. 令x为无穷序列表示的值,可以得到x*2^k = Y + x。 所以 x = Y/(2^k - 1)。 B. (a)1/7, (b)9/15 = 3/5, (c)7/63 = 1/9
    表示无穷的方法

    2.84##

    通过符号位来判断float的大小这种方法是有非常好的性质,因为浮点数的自然顺序就是如此
    还是漏掉了一种方法。
    有四种不同的情况
    一正一负
    都是零
    同正
    同负
    ((ux<<1)0 && (uy<<1)0) || (!sx && sy) || (!sx && !sy && ux >= uy) || (sx && sy && ux <= uy);

    2.85##

    有k位指数 n位小数
    写出阶码E,尾数M,小数f,和值V得公式

    数7.0###

    E =10011 (共k位)
    f =11000共n位
    尾数

    够被准确描述的最大奇整数###

    小数f 1111(全一 共N位 )
    阶码 10011 (值是n) 2^(n-1) 这么大
    值因该是
    11111111 有n+1个 1
    这个值是 2^n -1

    最小的规格化数的倒数###

    最小的规格化数
    阶码
    00000001 -2^(k-1) +2// 1-bios bios=2^(k-1)-1
    小数
    0000000 全零代表 1
    值 2{-2(k-1)+2}

    取导之后是
    2^{ 2^(k-1) -2}
    阶码是 11101 只有第1位是0 // 值应该是 2^k-1 -2 + bios
    2^(k-1)
    尾数是全零表示1

    阶数的符号表示不是补码表示,进行计算的时候要带上bios
    2^k-1 -1 这个是bios 换句话讲阶数等于0是这样的 01111111 大于零的阶数首位必定是1

    2.86##

    精度扩展的问题
    80位字节下浮点数的一些特值
    1 个符号位
    15个阶码位
    1个整数位 规格化数位1 非规格化数值为零
    63个小数位
    最小的 正非规格化数

    2^( -2^(14) +###2### ) * 2^(-63)
    //非规格化数阶数为1- bios 为了平滑的过渡
    3.645*10^(-4951)
    最小的正规格化数
    2(-214 +2 )
    最大的规格化数
    (2-2(-63))*2{2 ^(14))}

    2.87##

    在 一个符号位 五个阶码位 10个尾数位 时填表

    描述 Hex M E V D
    -0 8000 0 0 -0 *
    最小的大于2的值 4001 0000000001 10000 2 +2^-9 *
    512 6000 0000000000 11000 512 512.0
    最大非规格化数 7fff 1111111111 11111 (2 - 2^-10 )*2^16 *
    -∞ fc00 * * * *

    M 应该是小数值
    E 应该是阶码的值,我就不再改了

    2.88##

    浮点数的转换

    1 01110 001 -9/16 1 0110 0010 -9/16
    0 10110 101 416 0 1110 1010 416
    1 00111 110 -9/1024 0 0000 0111 -7/1024
    0 00000 101 5*2^12 0 0000 0000 0
    1 11011 000 -2^12 1 1111 0000 -∞
    0 11000 100 3*2^8 0 111 1111 (2-24)*28

    2.89##

    另外在32位的机子上double 和 flaot 是使用了80位的扩展精度(我的机子上只有longdouble 是80 位 的)
    喜闻乐见的找错误环节
    int x=random()
    double dx=(double)x
    A (float)x==(float)dx 错的,单精度浮点数误差 最多表示一个数最高位1和最低的1相差不超过24位的数 ,超过这个范围没有办法表示了
    B dx-dy (double)(x-y) 显然是错的
    C (dx+dy)+dz
    dx+(dy+dz) 经典的错误 浮点数的结合律会被舍入规则坑掉的
    D dx/dx=dz/dz 其中一个是0的话有可能出来Nan的

    2.90##

    偷个懒就是判断一些可以有效表示的范围

    2.91-2.97##

    实现在 flaot_bits 上的函数 我就先不写了

  • 相关阅读:
    Ubuntu 16 编译装python2.7
    配置ubunto 流量使用限制 python 实现简单 http server
    vnstat 流量统计 并附带一个小 php 查看流量的页面
    ubunto 免输入密码 登录 putty ssh-keygen
    nes 红白机模拟器 第5篇 全屏显示
    arm 添加 samb 文件共享
    arm 添加 ftp server 之 bftpd
    Tga图片格式分析以及程序实现
    领导力:刘邦的管理之道
    AS3:辨析ROLL_OVER与MOUSE_OVER,ROLL_OUT与MOUSE_OUT
  • 原文地址:https://www.cnblogs.com/sfzyk/p/7619897.html
Copyright © 2020-2023  润新知