繁体   English   中英

获取二进制的最后 n 位

[英]Get last n bits of binary

我正在做一个项目,我需要的是获取二进制文件的最后n位。 我尝试了一些东西,但我工作得不是很好。 这是代码:

long long int to_bin(int n)
{
     long long int Fin=0,pow=1;
     while(n)
     {
       Fin=Fin+(n%2)*pow;
       n/=2;pow*=10;
     }
 return Fin;
}           // returns binary 

int get_last_n_digits(int nr , int n_dig)
{
    int l_digits =0 , power = 1;
        for(int i = 0 ; i < n_dig ; i++)
            power *=10;
        l_digits = nr%power;
    return l_digits;
}         //returns last digits of a number

例如,我需要 245 的二进制表示的最后 2 位,即像这样:

get_last_n_digits(to_bin(254,S) ; 

结果是: 4 ; 怎么了 ?

演示

要读取/选择特定位置的位,您必须隐藏或屏蔽其余位。 实现此目的的一种方法是按位与: &运算符(不是逻辑与, && )。 假设我们在谈论一个 8 位数字,如果输入是 15,掩码是 7,结果是 7:

Input:  decimal 15 as binary: 0000 1111 &
Mask:   decimal  7 as binary: 0000 0111
------------------------------------------
Output: decimal  7 as binary: 0000 0111 

你的问题实际上是找到合适的面具。 如果要求您提供最后 4 位,则您的掩码应为0000 1111 (十进制 15,F 六进制)。 如果要求您输入最后两位数字,则您的掩码应为0000 0011 (3 位十进制数,3 位六进制数)。 找到最后 n 位掩码的步骤:

  1. 将所有位设置为 1。这可以通过取零来完成: ~0 -> 1111 1111 (255 十进制,FF 六进制)
  2. 左移n位: ~0 << n 如果 n 为 2,您将得到1111 1100
  3. 否定结果: ~(~0 << n) 如果 n 为 2,您将得到0000 0011

一旦你有了掩码,你所要做的就是使用按位与:

output = input & ~(~0 << n)

这就是你最终会得到的:

unsigned get_last_n_bits( unsigned u, int n )
{
  return u & ~(~0U << n);
}

使用标准流操作器无法以二进制形式显示结果。 您不能编写类似于cout << hex << number :没有bin操纵器。 但是,如果将数字转换为bitset ,则可以显示: cout << bitset< width >( number )

#include <iostream>
#include <bitset>
using namespace std;

unsigned get_last_n_bits( unsigned u, int n )
{
  return u & ~(~0U << n);
}

int main()
{
  cout << bitset<8>( get_last_n_bits( 254, 2 ) ); // displays 00000010
  return 0;
}

尝试

static inline long get_last_n_bits(long num, int nbbits) {
   return num & ((1L<<nbbits)-1);
}

并阅读有关二进制表示和按位运算的更多信息; 你甚至可以将num的类型作为模板参数......然后使用get_last_n_bits<long>get_last_n_bits<uint64_t>等......

然后测试get_last_n_bits(245,2)是否为 1。

你的术语是错误的,一个数字不是一个位,或者你应该说一个二进制数字

如果我正确理解你的答案(我不确定我是否理解;请澄清)你可以使用转变来解决这个问题:

int get_last_n_digits(int nr , int n_dig)
{
    int shift = (sizeof(nr) * 8) - n_dig;
    return (nr << shift) >> shift;
}

第一个移位(左)清除所有不需要的位,第二个将需要的位放回原位。

您正在做的是构建一个整数值,其十进制表示类似于输入值的二进制表示。 我听说过“Binary Coded Decimal”,所以我称它为“Decimal Coded Binary”。 哈哈!

将二进制表示作为某种字符串值来处理可能总是更好,而不是作为内部二进制编码的整数,当转换为十进制表示时,它恰好看起来像某个值的二进制表示。 但是,无论如何,弄清楚如何去做这样的事情是一种乐趣。

您的to_bin函数已经工作,所以我将其复制为DecimalCodedBinary

要砍掉高阶数字并保留以 B 为基数表示的数字的低 N 位数字,您只需要得到X (mod B^N) (其中 '^' 是幂运算)。

因此,为了使用基数 10,我创建了一个特殊函数Pow10 ,它返回 10 的参数幂。

最后, LowDigitsDecimal是一个正确实施get_last_n_digits ,返回nr % Pow10(n_dig)

#include <iostream>
#include <iomanip>

unsigned long long DecimalCodedBinary(unsigned int n) {
    unsigned long long pow10 = 1;
    unsigned long long result = 0;
    while(n) {
        result += pow10 * (n % 2);
        n /= 2;
        pow10 *= 10;
    }
    return result;
}

unsigned long long Pow10(int exponent) {
    if(exponent < 0) return 0;
    unsigned long long pow10 = 10;
    unsigned long long result = 1;
    while(exponent) {
        if(exponent % 2) result *= pow10;
        exponent /= 2;
        pow10 *= pow10;
    }
    return result;
}

unsigned long long LowDigitsDecimal(unsigned long long nr, int count) {
    unsigned long long modulo = Pow10(count);
    return nr % modulo;
}

int main() {
    unsigned long long dcb_val = DecimalCodedBinary(254);
    std::cout << dcb_val << "\n";
    unsigned long long dcb_val_low_2 = LowDigitsDecimal(dcb_val, 2);
    std::cout << std::setw(8) << std::setfill('0') << dcb_val_low_2 << "\n";

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM