获取最后n位二进制

时间:2016-03-11 14:19:21

标签: c++

我正在开发一个项目,我需要的是获取二进制文件的最后#!/usr/bin/env ruby # # https://gist.github.com/sheldonh/4693e2eca35b62b22c55 require 'openssl' require 'net/http' require 'json' class Gist DEFAULT_OPTIONS = { use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_PEER, keep_alive_timeout: 30, cert: OpenSSL::X509::Certificate.new(File.read('./client.cert.pem')), key: OpenSSL::PKey::RSA.new(File.read('./client.key.pem')) } def initialize(http = nil) if http @http = http else @http = Net::HTTP.start("api.github.com", 443, DEFAULT_OPTIONS) end end def fetch(id, file) response = @http.request Net::HTTP::Get.new "/gists/#{id}" JSON.parse(response.body)["files"][file]["content"] end end gist = Gist.new puts gist.fetch "fc5b5c42ff2e22171f09", "gistfile1.txt" # Lorem ipsum puts gist.fetch "4693e2eca35b62b22c55", "gist.rb" # This script 位。我尝试了一些东西,但是我工作得不好。这是代码:

n

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

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

结果是:4; 怎么了?

4 个答案:

答案 0 :(得分:5)

尝试

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。

您的术语有误,数字不是一点,或者您应该说二进制数字

答案 1 :(得分:3)

<强> Demo

要读取/选择特定位置的位,您必须隐藏或屏蔽其余位。实现此目的的一种方法是按位AND:&运算符(不是逻辑和&&)。假设我们正在讨论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 - &gt; 1111 1111(十进制255,FF六角)
  2. n位移至左侧:~0 << n。如果n为2,您将获得1111 1100
  3. 否定结果:~(~0 << n)。如果n为2,您将获得0000 0011
  4. 一旦你有了面具,你所要做的就是使用按位AND:

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

    这是你最终会得到的:

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

    使用标准流操纵器无法实现二进制库中的结果。你不能写类似于cout << hex << number的东西:没有bin操纵者。但是,如果号码转换为bitsetcout << 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;
    }
    

答案 2 :(得分:2)

如果我理解你的答案(我不确定,请澄清)你可以用轮班来解决这个问题:

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

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

答案 3 :(得分:2)

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

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

您的to_bin功能已经有效,因此我将其复制为DecimalCodedBinary

要切断高阶数字并保留基数B中代表的数字的低N位数,您只需要获得X (mod B^N)(其中'^'是取幂)。

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

最后,LowDigitsDecimalget_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";