假设数据是 1011 1001,掩码是 0111 0110,那么您有:
input data: 1011 1001
input mask: 0111 0110
apply mask: 0011 0000 (based on `input mask`)
bits selected: -011 -00- (based on `input mask`)
right packed: ---0 1100
expected result: 0000 1100 (set left `8 - popcount('input mask')` bits to zero)
所以最后的输出是0000 1100(注意左边3个未指定的位置用零填充)。
您可以看到,只要 input mask 中的位为 1,input data 中的相应值就会被选中(在 bits selected 上面),然后所有selected 位被连续打包在结果的最低有效位开始(如上面的right packed 所示)。最后,将打包后剩下的任何最左边的位设置为 0(将有 8 - popcount(mask) 这样的位)。
显而易见的选择是旋转和选择,但由于掩码有 5 位,这将消耗 5 次操作。我可以一步完成吗?
注意:
掩码可以是任意n位ON的任何东西(在上面
例如 n=5)。您所知道的是 ON 中的位数
面具和面具本身。掩码将随着 n 位 ON 不断变化。
在上面的示例中,我使用了 8 位的数据和掩码,但实际上 usage 它可以是 8、16、32、64 和 128 位。
最佳答案
如果您的目标是 x86,大多数编译器将具有 pdep ( parallel bit deposit) 指令的内在指令,该指令直接在硬件中执行您想要的操作,位于在支持它的 Intel 硬件上,每个周期 1 个的速率(3 个周期延迟)1。例如,gcc offers it作为 _pdep_u32 和 _pdep_u64 内部函数。
不幸的是,在 AMD Ryzen(唯一支持 BMI2 的 AMD 硬件)上,这个操作非常慢:每 18 个周期一个。如果非英特尔平台对您很重要,您可能希望有一个单独的代码路径来支持它们。
如果您不在 x86 上,您可以找到这些选项的通用实现 here - 您想要的特定操作是 expand_right - 其他部分可能会很有趣,因为它专门涵盖了处理字大小元素的简单情况。
在实践中,如果你真的要处理 8 位数据和掩码值,你可能只使用一个预先计算的查找表——要么是一个大的 8 位 x 8 位 = 65k,它涵盖所有 {data, mask } 组合并直接为您提供答案,或者一个包含所有 mask 值并为您提供一些用于简单位移计算或基于乘法的代码的系数的 256 项组合.
FWIW,我不确定如何使用 5 个循环指令轻松完成此操作,因为看起来天真的解决方案需要为每个位执行 1 个循环指令,无论是否设置(因此对于 8 位的字长, 7 或 8 个旋转2 指令)。
1 当然,原则上性能取决于硬件,但在所有实现它的主流 Intel CPU 上,它是 1 个周期的吞吐量,3 个周期的延迟(AMD 不确定)。
2 只有 7 旋转,因为显然可以省略最低位的“旋转 0”操作。
关于c++ - 我想根据任意掩码打包这些位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41617369/
总的来说,我对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
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
如何将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.你能做的最好的事情是:
我对如何计算通过{%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)
我需要根据字符串路径的长度将字符串路径数组转换为符号、哈希和数组的数组给定以下数组:array=["info","services","about/company","about/history/part1","about/history/part2"]我想生成以下输出,对不同级别进行分组,根据级别的结构混合使用符号和对象。产生以下输出:[:info,:services,about:[:company,history:[:part1,:part2]]]#altsyntax[:info,:services,{:about=>[:company,{:history=>[:part1,:pa
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=