如何多位来自多个用C返回

问题描述:

我有一个函数来提取一些单位:如何多位来自多个用C返回

int getBit (int value, int position) { 

    return value & (1 << position)); 

    } 

但是我怎么做到这一点的范围内(包括符号和无符号数) ?例如:

得到位从0×12345678 10:14(签字0)= 0×15

int getField (int value, int hi, int lo, bool isSigned) 
+0

从有符号数位提取时,你有什么期望?应该用最高的要求来扩大结果的符号吗? – usr2564301 2015-02-08 23:56:06

+0

难道你不想返回一个包含'1'和'0'的字符串吗? – 2015-02-08 23:59:48

+0

是的,但这不是我的问题,我的问题是找到一个工作算法来提取位。 – Velthuis 2015-02-09 00:02:06

你只需要创建一个面具:

int createMask(int a, int b){ 
int c = a; 
int mask = 0; 
/*First we set the lenght of the mask*/ 
while(c <= b){ /*Including b*/ 
mask <<= 1; 
mask = mask|1; 
c++; 
} 
/*Then we set the position to the mask, the first bit is in the position 0*/ 
c=0; 
while(c<a){ 
c++; 
mask <<= 1 ; 

} 
return mask; 
} 

我没有测试功能,但它只是为了解释制作面具的方式。

和最终功能可能是这样的:

int getBits(int value, int a, int b){ 
int mask = createMask(a, b); 
mask &= value; 
//Now we have to move the bits to the right 
while(a>0){ 
mask >>= 1; 
a--; 
} 
return mask; 

} 

一个例子,如果你想第6位,你必须代码:getBits(myvalue的,0,5)。

林不知道你是什么意思关于签名和无符号数字,但我希望它可以帮助你。

甩掉我的英语。

我怀疑你可能想以不同的方式处理整个问题。为什么不使用位掩码而不是提取位?

例如,要检查一个字节中最显著位有效:

if(byte & 0xf0) {} 

要检查至少显著位将是:

if(byte & 0x01) {} 

检查多个(或一个“范围”)位,比如低位半字节:

if(byte & 0x0f) {} 

从你所说的,我怀疑这是m这更接近你想要的并且比转换提取比特简单得多。

那是一点乐趣:)三个简单的步骤:

  1. 转变你的经量lo权值和lo减少hi。这简化了“获得最低位hi位”的问题。

  2. 剪掉最高位 - 自定义掩码随即创建。

  3. 如有必要,请使用最高位来签名扩展结果(根据Sign extending from a constant bit width in C#找到bit bit)。

我不知道建议的函数原型的原因,但我会建议使用顺序lo, hi而非hi, lo。不知何故10,14感觉比其他方式更自然,即使位数从高到低倒数,从左到右数 - 计算机应该让我们更容易!

#include <stdio.h> 
#include <stdbool.h> 

int getField (int value, int hi, int lo, bool isSigned) 
{ 
    /* step 1: clip off lower bits */ 
    value >>= lo; 
    hi -= lo-1; 
    /* step 2: clip off higher bits */ 
    value &= ~(-1<<hi); 
    /* step 3: extend sign */ 
    if (isSigned && (value & (1<<(hi-1)))) 
     value |= -(1<<hi); 
    return value; 
} 

int main (void) 
{ 
    int i; 
    i = getField (0x123456c8, 14,10, true); 
    printf ("i = %d/%Xh\n", i,i); 
    return 0; 
} 

结果:

i = -11/FFFFFFF5h 

这是正确的位设置:

16 12 8 4 0 <- bit position 
...4 5 6 7 8 <- value 
0100 0101 0110 0111 1000 <- bitwise 
     --- --    <- mask 
     101 01    <- result 
..111101 01    < sign extended result