我正在开发一个项目,我需要的是获取二进制文件的最后#!/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; 怎么了?
答案 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位掩码的步骤:
~0
- &gt; 1111 1111
(十进制255,FF六角)n
位移至左侧:~0 << n
。如果n为2,您将获得1111 1100
~(~0 << n)
。如果n为2,您将获得0000 0011
。一旦你有了面具,你所要做的就是使用按位AND:
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;
}
答案 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的参数。
最后,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";