rtklib函数解析

1.getbitu函数

extern unsigned int getbitu(const unsigned char *buff, int pos, int len)
{
    unsigned int bits=0;
    int i;
    for (i=pos;i<pos+len;i++)
        bits=(bits<<1)+((buff[i/8]>>(7-i%8))&1u);
    return bits;
}

解析:
(1)buff存放的是8位的字节,比如定义
unsigned char buff[]={0x8B,0x02,0x84,0x3E,0x56,0x26,0x28,0x50};
(2)算法:
比如getbitu(buff,43,3): 获取buff第43位置,长度为3.
a.定位置
位置是从0开始,小于32.
因为每个字节8为,43/8=5 余3,所以要找的位置是第6个字节0x26 即buff[i/8] 
而0x26=b00100110=bit40~bit47) 从左往右,所以取的值是 001
b. 取bit
7-i%8=3或4或5
0x26依次往右移3位,4位,5位, 依次取出bit43,bit44,bit45, 通过bits<<1叠加 

2.getbits函数
如果是负数,给bits添加符号,测试平台是linux 64bit 系统
return (int)(bits|(~0u<<len)); /* extend sign */  // 0xfffffff9 

~0u=0xffffffff
~0u<<len=0xfffffff9
(int)(0xfffffff9): 因为强加了int类型,系统会把它当成负数直接输出0xfffffff9的补码,结果为-7


linux平台测试如下:

#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>

unsigned int getbitu(const unsigned char *buff, int pos, int len)
{
    unsigned int bits=0;
    int i;
    for (i=pos;i<pos+len;i++){
                bits=(bits<<1)+((buff[i/8]>>(7-i%8))&1u);
                printf("i=%d,buff[%d/8]=0x%.02x\n",i,i,buff[i/8]);
        }
    return bits;
}


 int getbits(const unsigned char *buff, int pos, int len)
{
    unsigned int bits=getbitu(buff,pos,len);
    if (len<=0||32<=len||!(bits&(1u<<(len-1)))) return (int)bits;
    return (int)(bits|(~0u<<len)); /* extend sign */  // 0xfffffff9
}

void main()
{
        //unsigned char buff[]={0x8B,0x02,0x84,0x3E,0x56,0x26};
         unsigned char buff[]={0x8B,0x02,0x84,0x3E,0x56,0x26,0x28,0x50,0x00,0x6A,0xA8,0xA5,0xB6,0xDE,0xDB,0x14,0x7A,0xFB,0x08,0x49,0xEA ,0x39,0x2F,0x76, 0x00,0x00,0x02,0x15,0x1A,0x6A};
         signed char sbuf[]={0x91,0x81};
         unsigned char usbuf[]={0x91,0x81};
        unsigned int uint,len,uval;
        int sval;
        //uint=getbitu(buff,43,3);
        sval=getbits(sbuf,0,4);
        uval=getbitu(usbuf,0,4);
        //printf("unit=%.02x\n",unit);
        printf("sval=%d,uval=%d\n",sval,uval);

}

结果为:sval=-7,uval=9
问题为啥sval=-7而不是9, 两者取出的都是第一个字节的高4位即1001但是sbuf里的数据是signed int有符号类型,所以取出的1001中最位1为符号位. 1为负号.所以此数为负数,值为它的补码:
~(1001)+1  ->b0110+1=b0111=7.  所以最后为-7

补充知识点:
计算机存放正负数规则:
正数: 原码存放
负数: 补码存放
原码: 比如一个正数为9,存放在计算机中为b00001001=0x09。 如果一个负数为-9,存放在计算器机
的是9的补码=原码取反+1=~(00001001)+1=11110110+1=11110111=0xF7
反码: 原码取反
补码: 原码取反+1 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值