duanfanta6741 2018-01-23 17:05
浏览 113
已采纳

按位移位以及此解决方案为何起作用

I've been doing code fights on codefights.com and I came upon this problem below. I have figured out the problem on my own, but when i researched other peoples solutions I found one that was much shorter than mine, but I cant seem to understand why they did what they did.

The question goes:

You are given an array of up to four non-negative integers, each less than 256. Your task is to pack these integers into one number M in the following way:

The first element of the array occupies the first 8 bits of M; The second element occupies next 8 bits, and so on. Return the obtained integer M.

Note: the phrase "first bits of M" refers to the least significant bits of M - the right-most bits of an integer. For further clarification see the following example.

Example

For a = [24, 85, 0], the output should be arrayPacking(a) = 21784.

An array [24, 85, 0] looks like [00011000, 01010101, 00000000] in binary. After packing these into one number we get 00000000 01010101 00011000 (spaces are placed for convenience), which equals to 21784.

Their answer was:

func arrayPacking(a []int) (sum int) {
    for i := range a {
        sum += a[len(a) - i - 1] << uint((len(a) - i - 1) * 8)
    }
    return
}

How is this code returning the right amount of shift just by using 0, 8, 16, etc. intervals? I've been researching bitwise a lot lately, but I still can't seem to reason why this works.

  • 写回答

2条回答 默认 最新

  • draxq02664 2018-01-23 19:32
    关注

    First, write the solution in Go. We convert little-endian, base-256 digits to a base-2 (binary) number. Shifting left by 8 bits multiplies by 256.

    package main
    
    import (
        "fmt"
    )
    
    func pack(digits []int) (number int) {
        // digits are little-endian, base-256 (1 << 8 = 256)
        for i, digit := range digits {
            number += digit << uint(i*8)
        }
        return number
    }
    
    func main() {
        a := []int{24, 85, 0}
        m := pack(a)
        fmt.Println(m)
    }
    

    Playground: https://play.golang.org/p/oo_n7CiAHwG

    Output:

    21784
    

    Now you should be able to figure out their ugly looking answer:

    func arrayPacking(a []int) (sum int) {
        for i := range a {
            sum += a[len(a) - i - 1] << uint((len(a) - i - 1) * 8)
        }
        return
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 vscode问题请教
  • ¥50 切换TabTip键盘的输入法
  • ¥15 可否在不同线程中调用封装数据库操作的类
  • ¥15 微带串馈天线阵列每个阵元宽度计算
  • ¥15 keil的map文件中Image component sizes各项意思
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据
  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 Centos / PETGEM