Golang练习切片如何处理大值

时间:2016-08-20 02:27:13

标签: go

我正在阅读Golang教程,我对它在切片练习中的某些值所做的事情感到有些困惑。 https://tour.golang.org/moretypes/18

以下是我感到困惑的代码:

值0是完美的蓝色像素,值255是完全白色的像素。那么当显示的值是某种形式的x*y时我发生了什么(我做了/20以使图像更大更容易看到)。

如果您水平跟随图像,您将看到在该过程中的某个点,不断增加的x和y值似乎恢复为蓝色(0值)如果我键入一个静态值,如256 in返回我得到编译错误。所以它显然不允许数字go off the scale并恢复为0或任何东西。那么如何获得图片中的蓝色曲线呢?

导入来源:https://github.com/golang/tour/blob/master/pic/pic.go#L15

package main

import "golang.org/x/tour/pic"

func Pic(dx, dy int) [][]uint8 {
    //First, the array has to be made so we can put some values in it later
    //This only makes the second dimension of the array ([[uint8 dy]])?
    image := make([][]uint8, dy)

    //The inputs into the function are Int's, so it is ok to have a non uint8
    //loop initializer
    for x := 0; x < dy; x++ {
        //once we are in the loop we have to make the first dimension of the array
        //based on the dx values
        image[x] = make([]uint8, dx)
        for y := 0; y < dx; y++ {
            //This is a function +to assign the pixel values to the array
            image[x][y] = uint8((x * y) /20)
        }
    }
    return image
}

func main() {
    pic.Show(Pic)
}

2 个答案:

答案 0 :(得分:1)

uint8(anotherIntValue)转换将占用anotherIntValue的最后一个字节。这就是为什么你的代码可以生成许多蓝色(0)。例如,以下代码将打印'val = 0'。

dx, dy := 128, 2
fmt.Println("val =", uint8(dx*dy))

编译器将检查常量转换是否超出范围错误。

答案 1 :(得分:1)

想象一下,i的类型为intuint8(i)返回i的{​​{3}}:

x[0, 255]范围内时,意思是:0 <= x <= 255
并且y在范围[0,255],
中 然后x*y[0, 255*255] = [0, 65025]范围内 因此x*y/20位于[0, 255*255/20] = [0, 65025/20] = [0, 3251]范围内 uint8(x*y/20)的值等于(x*y/20)%256,意思是LSB字节:
uint8(3251) = uint8(0XCB3) = 0XB3 = 179
3251 = 12*256 + 179

因此,每当x*y/20大于255时,它都会从0开始计算:(x*y/20) % 256这就是为什么您的图像是重复的圆圈。

试试这个有效的示例代码:

package main

import "fmt"

func main() {
    for y := 0; y <= 255; y++ {
        for x := 0; x <= 255; x++ {
            v := x * y / 20
            if int(uint8(v)) != v%256 {
                fmt.Println(v, v%256)
            }
        }
    }
    fmt.Println("Done.")
}

输出:

Done.

让我们简化您的示例,请参阅此示例代码:

package main

import (
    "bytes"
    "image"
    "image/png"
    "os"
)

func main() {
    const dx = 256
    const dy = 256
    m := image.NewNRGBA(image.Rect(0, 0, dx, dy))
    for y := 0; y < dy; y++ {
        for x := 0; x < dx; x++ {
            v := uint8(x * y / 20)
            i := y*m.Stride + x*4
            m.Pix[i] = v     //R
            m.Pix[i+1] = v   //G
            m.Pix[i+2] = 255 //B
            m.Pix[i+3] = 255 //A
        }
    }
    var buf bytes.Buffer
    err := png.Encode(&buf, m)
    if err != nil {
        panic(err)
    }
    os.Stdout.Write(buf.Bytes())
}

并将输出重定向到main > b.pnggo run main.go > b.png之类的文件 请参阅输出文件b.png
Least Significant Byte (LSB)