有没有高性能的C/C++库,支持任意位置的位操作?
例如:
int BitCompare(const void* src, size_t srcOffsetInBits, const void* dst, size_t dstOffsetInBits, size_t sizeInBits);
比较 src 中的位 [srcOffsetInBits, srcOffsetInBits + sizeInBits - 1] 和 dst 中的 [dstOffsetInBits, dstOffsetInBits + sizeInBits - 1] 的函数,这些位被认为是 little- endian 无符号整数。假定所有缓冲区都足够大。
bool BitEqual(...);
void BitMove(...);//src 和 dst 可以重叠。
void BitCopy(...);//src 和 dst 不能重叠。
所有操作应该只修改正在操作的位,其他所有位都应该保留。
我做了一些尝试来实现 BitCompare。
static uint8_t mask8l1[9] = {
0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF
};
static uint8_t mask8l0[9] = {
0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80, 0x00
};
// Offset-less compare.
int BitCompare8(const void* src, const void* dst, size_t sizeInBits)/*{{{*/
{
const uint8_t* _src = static_cast<const uint8_t*>(src);
const uint8_t* _dst = static_cast<const uint8_t*>(dst);
size_t sizeInUint8s = sizeInBits >> 3;
size_t sizeRemaining = sizeInBits & 0x07;
// MSB ---> LSB
// : bits-to-compare :
// ----------------------------------------- ---------------------
// | : sizeRemaining | | ... | |
// ----------------------------------------- ---------------------
// @_src + sizeInUint8s @_src
//
// ----------------------------------------- ---------------------
// | : sizeRemaining | | ... | |
// ----------------------------------------- ---------------------
// @_dst + sizeInUint8s @_dst
_src += sizeInUint8s;
_dst += sizeInUint8s;
// Compare the MSB sizeRemaining bits first.
if (sizeRemaining)
{
// : sizeRemaining :
// ----------------------
// | : s |
// ----------------------
// @_src
// : sizeRemaining :
// ----------------------
// | : d |
// ----------------------
// @_dst
uint8_t s = *_src & mask8l1[sizeRemaining];
uint8_t d = *_dst & mask8l1[sizeRemaining];
if (s < d)
{
return -1;
}
else if (d < s)
{
return 1;
}
}
// Then compare the LSB uint8s.
while (sizeInUint8s)
{
// ----------------------
// | s |
// ----------------------
// @_src - 1
// ---------------------
// | d |
// ---------------------
// @_dst - 1
uint8_t s = *--_src;
uint8_t d = *--_dst;
if (s < d)
{
return -1;
}
else if (d < s)
{
return 1;
}
--sizeInUint8s;
}
return 0;
}/*}}}*/
// Source-side offset compare.
int BitCompare8(const void* src, size_t offsetInBits, /*{{{*/
const void* dst, size_t sizeInBits)
{
const uint8_t* _src = static_cast<const uint8_t*>(src);
const uint8_t* _dst = static_cast<const uint8_t*>(dst);
_src += offsetInBits >> 3;
offsetInBits &= 0x07;
if (!offsetInBits)
{
return BitCompare8(_src, _dst, sizeInBits);
}
size_t sizeInUint8s = sizeInBits >> 3;
size_t sizeRemaining = sizeInBits & 0x07;
// MSB ---> LSB
// : bits-to-compare :
// : sizeRemaining : :
// ----------------------------------------- ---------------------
// | | : offsetInBits | ... | : offsetInBits |
// ----------------------------------------- ---------------------
// @_src + sizeInUint8s @_src
//
// ----------------------------------------- ---------------------
// | : sizeRemaining | | ... | |
// ----------------------------------------- ---------------------
// @_dst + sizeInUint8s @_dst
_src += sizeInUint8s;
_dst += sizeInUint8s;
// Move the MSB sizeRemaining bits first.
if (sizeRemaining)
{
if (sizeRemaining + offsetInBits <= 8)
{
// : sizeRemaining :
// ----------------------------------
// | : s : offsetInBits |
// ----------------------------------
// @_src
// : sizeRemaining :
// ----------------------------------
// | : d |
// ----------------------------------
// @_dst
uint8_t s = (*_src >> offsetInBits) & mask8l1[sizeRemaining];
uint8_t d = *_dst & mask8l1[sizeRemaining];
if (s < d)
{
return -1;
}
else if (d < s)
{
return 1;
}
}
else // if (sizeRemaining + offsetInBits > 8)
{
// : sizeRemaining :
// -------------------------------------------------------------------
// | : a | b : offsetInBits |
// -------------------------------------------------------------------
// @_src + 1 @_src
//
// : sizeRemaining :
// ----------------------------------
// | : a : b |
// ----------------------------------
// : : @_dst
// : offsetInBits :
//
// a = sizeRemaining - (8 - offsetInBits)
// b = 8 - offsetInBits
//
// Note: offsetInBits > 8 - sizeRemaining > 0
// a < 8
uint8_t a = (*(_src + 1) << (8 - offsetInBits))
& mask8l1[sizeRemaining];
uint8_t b = *_src >> offsetInBits;
uint8_t s = a | b;
uint8_t d = *_dst & mask8l1[sizeRemaining];
if (s < d)
{
return -1;
}
else if (d < s)
{
return 1;
}
}
}
// Then move the LSB uint8s.
while (sizeInUint8s)
{
// : offsetInBits :
// -----------------------------------------
// | : a | b : offsetInBits |
// -----------------------------------------
// @_src @_src - 1
// : offsetInBits :
// ---------------------
// | a : b |
// ---------------------
// @_dst - 1
//
uint8_t a = *_src << (8 - offsetInBits);
uint8_t b = *--_src >> offsetInBits;
uint8_t s = a | b;
uint8_t d = *--_dst;
if (s < d)
{
return -1;
}
else if (d < s)
{
return 1;
}
--sizeInUint8s;
}
return 0;
}/*}}}*/
// Destination-side offset compare.
int BitCompare8(const void* src, /*{{{*/
const void* dst, size_t offsetInBits,
size_t sizeInBits)
{
return -BitCompare8(dst, offsetInBits, src, sizeInBits);
}/*}}}*/
// Generic compare.
int BitCompare8(const void* src, size_t srcOffsetInBits, /*{{{*/
const void* dst, size_t dstOffsetInBits,
size_t sizeInBits)
{
const uint8_t* _src = static_cast<const uint8_t*>(src);
const uint8_t* _dst = static_cast<const uint8_t*>(dst);
_src += srcOffsetInBits >> 3;
srcOffsetInBits &= 0x07;
if (!srcOffsetInBits)
{
return -BitCompare8(_dst, dstOffsetInBits, _src, sizeInBits);
}
_dst += dstOffsetInBits >> 3;
dstOffsetInBits &= 0x07;
if (!dstOffsetInBits)
{
return BitCompare8(_src, srcOffsetInBits, _dst, sizeInBits);
}
size_t sizeInUint8s = sizeInBits >> 3;
size_t sizeRemaining = sizeInBits & 0x07;
// MSB ---> LSB
// : bits-to-compare :
// : sizeRemaining : :
// ----------------------------------------------- ------------------------
// | | : srcOffsetInBits | ... | : srcOffsetInBits |
// ----------------------------------------------- ------------------------
// @_src + sizeInUint8s @_src
//
// : sizeRemaining :
// ----------------------------------------------- ------------------------
// | | : dstOffsetInBits | ... | : dstOffsetInBits |
// ----------------------------------------------- ------------------------
// @_dst + sizeInUint8s @_dst
if (srcOffsetInBits <= dstOffsetInBits)
{
// : sizeRemaining :
// -----------------------------------------------
// | | : srcOffsetInBits |
// -----------------------------------------------
// @_src
//
// : sizeRemaining :
// -----------------------------------------------
// | | : dstOffsetInBits |
// -----------------------------------------------
// @_dst
if (!sizeInUint8s)
{
if (sizeRemaining + dstOffsetInBits <= 8)
{
// : sizeRemaining :
// -----------------------------------------------
// | : s : srcOffsetInBits |
// -----------------------------------------------
// @_src
//
// : sizeRemaining :
// -----------------------------------------------
// | : d : dstOffsetInBits |
// -----------------------------------------------
// @_dst
// There're only sizeRemaining bits to compare.
uint8_t s = (*_src >> srcOffsetInBits)
& mask8l1[sizeRemaining];
uint8_t d = (*_dst >> dstOffsetInBits)
& mask8l1[sizeRemaining];
if (s < d)
{
return -1;
}
else if (d < s)
{
return 1;
}
}
else // if (sizeRemaining + dstOffsetInBits > 8)
{
// : sizeRemaining :
// -------------------------------------------------
// | : a | b : srcOffsetInBits |
// -------------------------------------------------
// @_src
//
// : sizeRemaining :
// -------------------------------------------------
// | : a | b : dstOffsetInBits |
// -------------------------------------------------
// @_dst + 1 @_dst
uint8_t a = *_src++ >> srcOffsetInBits;
uint8_t b = (*_src << (8 - srcOffsetInBits))
& mask8l1[sizeRemaining];
uint8_t s = a | b;
a = *_dst++ >> dstOffsetInBits;
b = (*_dst << (8 - dstOffsetInBits))
& mask8l1[sizeRemaining];
uint8_t d = a | b;
if (s < d)
{
return -1;
}
else if (d < s)
{
return 1;
}
}
return 0;
}
// There're more than (8 - dstOffsetInBits) bits to compare.
// Compare MSB bits first.
// <- MSB bits to compare ->:
// :---:>(8 - dstOffsetInBits)
// : sizeRemaining :
// -------------------------------------------------
// | : | : s : srcOffsetInBits |
// -------------------------------------------------
// @_src
//
// <- MSB bits to compare ->:
// : sizeRemaining :
// -------------------------------------------------
// | : | d : dstOffsetInBits |
// -------------------------------------------------
// @_dst + 1 @_dst
int result = BitCompare8(
_src, srcOffsetInBits + (8 - dstOffsetInBits),
_dst + 1, sizeInBits - (8 - dstOffsetInBits));
if (result)
{
return result;
}
// Then compare LSB (8 - dstOffsetInBits) bits.
uint8_t s = (*_src >> srcOffsetInBits) & mask8m0[dstOffsetInBits];
uint8_t d = *_dst++ >> dstOffsetInBits;
if (s < d)
{
return -1;
}
else if (d < s)
{
return 1;
}
}
else // if (dstOffsetInBits < srcOffsetInBits)
{
// : sizeRemaining :
// -----------------------------------------------
// | | : srcOffsetInBits |
// -----------------------------------------------
// @_src
//
// : sizeRemaining :
// -----------------------------------------------
// | | : dstOffsetInBits |
// -----------------------------------------------
// @_dst
if (!sizeInUint8s)
{
if (sizeRemaining + srcOffsetInBits <= 8)
{
// : sizeRemaining :
// -----------------------------------------------
// | : s : srcOffsetInBits |
// -----------------------------------------------
// @_src
//
// : sizeRemaining :
// -----------------------------------------------
// | : d : dstOffsetInBits |
// -----------------------------------------------
// @_dst
// There're only sizeRemaining bits to compare.
uint8_t s = (*_src >> srcOffsetInBits)
& mask8l1[sizeRemaining];
uint8_t d = (*_dst >> dstOffsetInBits)
& mask8l1[sizeRemaining];
if (s < d)
{
return -1;
}
else if (d < s)
{
return 1;
}
}
else // if (sizeRemaining + srcOffsetInBits > 8)
{
// : sizeRemaining :
// -------------------------------------------------
// | : a | b : srcOffsetInBits |
// -------------------------------------------------
// @_src + 1 @_src
//
// : sizeRemaining :
// -------------------------------------------------
// | : a | b : dstOffsetInBits |
// -------------------------------------------------
// @_dst + 1 @_dst
uint8_t a = *_src++ >> srcOffsetInBits;
uint8_t b = (*_src << (8 - srcOffsetInBits))
& mask8l1[sizeRemaining];
uint8_t s = a | b;
a = *_dst++ >> dstOffsetInBits;
b = (*_dst << (8 - dstOffsetInBits))
& mask8l1[sizeRemaining];
uint8_t d = a | b;
if (s < d)
{
return -1;
}
else if (d < s)
{
return 1;
}
}
return 0;
}
// There're more than (8 - srcOffsetInBits) bits to compare.
// Compare MSB bits first.
//
// <- MSB bits to compare ->:
// : sizeRemaining :
// -------------------------------------------------
// | : | s : srcOffsetInBits |
// -------------------------------------------------
// @_src + 1 @_src
//
// <- MSB bits to compare ->:
// :---:>(8 - srcOffsetInBits)
// : sizeRemaining :
// -------------------------------------------------
// | : | : d : dstOffsetInBits |
// -------------------------------------------------
// @_dst + 1 @_dst
int result = BitCompare8(
_dst, dstOffsetInBits + (8 - srcOffsetInBits),
_src + 1, sizeInBits - (8 - srcOffsetInBits));
if (result)
{
return result;
}
// Then compare LSB (8 - srcOffsetInBits) bits.
uint8_t s = *_src++ >> srcOffsetInBits;
uint8_t d = (*_dst >> dstOffsetInBits) & mask8m0[srcOffsetInBits];
if (s < d)
{
return -1;
}
else if (d < s)
{
return 1;
}
}
return 0;
}/*}}}*/
最佳答案
GNU Multiprecision Arithmetic library支持任意长整数的按位运算,并提供C++接口(interface)。
关于c++ - 有没有支持任意位置位操作的高性能C/C++库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18556099/
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我在Rails应用程序中使用CarrierWave/Fog将视频上传到AmazonS3。有没有办法判断上传的进度,让我可以显示上传进度如何? 最佳答案 CarrierWave和Fog本身没有这种功能;你需要一个前端uploader来显示进度。当我不得不解决这个问题时,我使用了jQueryfileupload因为我的堆栈中已经有jQuery。甚至还有apostonCarrierWaveintegration因此您只需按照那里的说明操作即可获得适用于您的应用的进度条。 关于ruby-on-r
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我需要一个非常简单的字符串验证器来显示第一个符号与所需格式不对应的位置。我想使用正则表达式,但在这种情况下,我必须找到与表达式相对应的字符串停止的位置,但我找不到可以做到这一点的方法。(这一定是一种相当简单的方法……也许没有?)例如,如果我有正则表达式:/^Q+E+R+$/带字符串:"QQQQEEE2ER"期望的结果应该是7 最佳答案 一个想法:你可以做的是标记你的模式并用可选的嵌套捕获组编写它:^(Q+(E+(R+($)?)?)?)?然后你只需要计算你获得的捕获组的数量就可以知道正则表达式引擎在模式中停止的位置,你可以确定匹配结束
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我有一个使用SeleniumWebdriver和Nokogiri的Ruby应用程序。我想选择一个类,然后对于那个类对应的每个div,我想根据div的内容执行一个Action。例如,我正在解析以下页面:https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=puppies这是一个搜索结果页面,我正在寻找描述中包含“Adoption”一词的第一个结果。因此机器人应该寻找带有className:"result"的div,对于每个检查它的.descriptiondiv是否包含单词“adoption
RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)
我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?
在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.