【问题标题】:Combine four 8-bit unsigned ints into one 32-bit unsigned int将四个 8 位无符号整数组合成一个 32 位无符号整数
【发布时间】:2014-12-12 04:41:40
【问题描述】:

给定一个由四个 8 位无符号整数组成的数组,例如 32-bit RGBA color

rgba = [255, 255, 255, 255] # white

将这四个 Fixnums 组合成一个 32 位 Integer 的最有效方法是什么?

目前,我正在使用打包和解包:

rgba.pack('C*').unpack('L')[0] #=> 4294967295

# Check work: same value as corresponding hex literal
0xffffffff #=> 4294967295

但我想知道是否有更有效的方法。我发现了这个 C++ 问题:

Cleanest way to combine two shorts to an int

我认为<< 是一个“移位”,| 是一个“掩码”,但我对这些运算符了解不够,并且从未在 ruby​​ 中使用过它们。

【问题讨论】:

    标签: ruby bit-manipulation


    【解决方案1】:

    将每个元素移动 24 - (index * 8),然后将它们全部或在一起:

    rgba = [255, 255, 255, 255]
    rgba[0] << 24 | rgba[1] << 16 | rgba[2] << 8 | rgba[3]
    

    我没有移位 rgba[3],因为移位为零没有效果。

    一些测量:

    使用unpack

    Benchmark.measure do
      100_000.times do
        rgba = [255, 255, 255, 255]
        rgba.pack('C*').unpack('L')[0]
      end
    end
    

    结果:

    => #<Benchmark::Tms:0x007fe137005350
     @cstime=0.0,
     @cutime=0.0,
     @label="",
     @real=0.146899,
     @stime=0.0,
     @total=0.1399999999999999,
     @utime=0.1399999999999999>
    

    使用位运算符

    Benchmark.measure do
      100_100.times do
        rgba = [255, 255, 255, 255]
        rgba[0] << 24 | rgba[1] << 16 | rgba[2] << 8 | rgba[3]
      end
    end
    

    结果:

    => #<Benchmark::Tms:0x007fd66438fd28
     @cstime=0.0,
     @cutime=0.0,
     @label="",
     @real=0.088995,
     @stime=0.0,
     @total=0.08000000000000007,
     @utime=0.08000000000000007>
    

    【讨论】:

    • 酷。很高兴您可以在没有一堆括号的情况下链接 OR,就像在 C++ 示例中一样。非常感谢您提供基准!
    • @JaredBeck 我相当肯定该示例中的大多数括号都是不必要的,但为了可读性而包含在内(|&amp; 的优先级高于 &lt;&lt; - 根据@987654321 @)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 2019-05-30
    相关资源
    最近更新 更多