1. 程式人生 > 其它 >Go語言聖經閱讀-第六週

Go語言聖經閱讀-第六週

技術標籤:技術分享

3.3. 複數

Go語言提供了兩種精度的複數型別:complex64和complex128,分別對應float32和float64兩種浮點數精度。內建的complex函式用於構建複數,內建的real和imag函式分別返回複數的實部和虛部:

var x complex128 = complex(1, 2) // 1+2i
var y complex128 = complex(3, 4) // 3+4i
fmt.Println(x*y)                 // "(-5+10i)"
fmt.Println(real(x*y))           // "-5"
fmt.Println(imag(x*y))           // "10"

如果一個浮點數面值或一個十進位制整數面值後面跟著一個i,例如3.141592i或2i,它將構成一個複數的虛部,複數的實部是0:

fmt.Println(1i * 1i) // "(-1+0i)", i^2 = -1

在常量算術規則下,一個複數常量可以加到另一個普通數值常量(整數或浮點數、實部或虛部),我們可以用自然的方式書寫複數,就像1+2i或與之等價的寫法2i+1。上面x和y的宣告語句還可以簡化:

x := 1 + 2i
y := 3 + 4i

複數也可以用==和!=進行相等比較。只有兩個複數的實部和虛部都相等的時候它們才是相等的(譯註:浮點數的相等比較是危險的,需要特別小心處理精度問題)。

math/cmplx包提供了複數處理的許多函式,例如求複數的平方根函式和求冪函式。

fmt.Println(cmplx.Sqrt(-1)) // "(0+1i)"

下面的程式使用complex128複數演算法來生成一個Mandelbrot影象。

gopl.io/ch3/mandelbrot

// Mandelbrot emits a PNG image of the Mandelbrot fractal.
package main

import (
    "image"
    "image/color"
    "image/png"
    "math/cmplx"
    "os"
)


func main() {
    const (
        xmin, ymin, xmax, ymax = -2, -2, +2, +2
        width, height          = 1024, 1024
    )

    img := image.NewRGBA(image.Rect(0, 0, width, height))
    for py := 0; py < height; py++ {
        y := float64(py)/height*(ymax-ymin) + ymin
        for px := 0; px < width; px++ {
            x := float64(px)/width*(xmax-xmin) + xmin
            z := complex(x, y)
            // Image point (px, py) represents complex value z.
            img.Set(px, py, mandelbrot(z))
        }
    }
    png.Encode(os.Stdout, img) // NOTE: ignoring errors
}

func mandelbrot(z complex128) color.Color {
    const iterations = 200
    const contrast = 15

    var v complex128
    for n := uint8(0); n < iterations; n++ {
        v = v*v + z
        if cmplx.Abs(v) > 2 {
            return color.Gray{255 - contrast*n}
        }
    }
    return color.Black
}

用於遍歷1024x1024影象每個點的兩個巢狀的迴圈對應-2到+2區間的複數平面。程式反覆測試每個點對應複數值平方值加一個增量值對應的點是否超出半徑為2的圓。如果超過了,通過根據預設定的逃逸迭代次數對應的灰度顏色來代替。如果不是,那麼該點屬於Mandelbrot集合,使用黑色顏色標記。最終程式將生成的PNG格式分形影象輸出到標準輸出,如圖3.3所示。