Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Pergi: Bagaimana untuk menyemak kehilangan ketepatan apabila menukar float64 kepada float32

Pergi: Bagaimana untuk menyemak kehilangan ketepatan apabila menukar float64 kepada float32

WBOY
WBOYke hadapan
2024-02-09 09:10:20460semak imbas

Go:如何检查将 float64 转换为 float32 时的精度损失

Editor PHP Baicao hari ini memperkenalkan anda kepada penyelesaian kepada masalah biasa: cara menyemak kehilangan ketepatan yang mungkin berlaku apabila menukar float64 kepada float32. Apabila menukar nombor titik terapung, kehilangan ketepatan mungkin berlaku disebabkan oleh perbezaan bilangan bit antara kedua-dua jenis data. Artikel ini akan memperincikan cara untuk menentukan sama ada terdapat kerugian dengan membandingkan nilai sebelum dan selepas penukaran, dan menyediakan penyelesaian yang boleh dilaksanakan untuk membantu pembangun menangani masalah ini dengan lebih baik.

Kandungan soalan

Saya mempunyai senario di mana saya menerima nilai float64 tetapi perlu menghantarnya melalui wayar ke perkhidmatan lain sebagai nilai float32. Kami tahu bahawa nilai yang diterima harus sentiasa sesuai dengan float32. Walau bagaimanapun, hanya untuk berada di bahagian yang selamat, saya ingin merekodkan bahawa kami kehilangan data dengan menukar kepada float32 .

Blok kod ini tidak akan disusun kerana anda tidak boleh membandingkan float32 dengan float64 secara langsung.

func convert(input float64) (output float32, err error) {
    const tolerance = 0.001
    output = float32(input)
    if output > input+tolerance || output < input-tolerance {
        return 0, errors.New("lost too much precision")
    }
    return output, nil
}

Adakah cara mudah untuk menyemak sama ada saya mengalami ini? Semakan ini kerap berlaku jadi saya ingin mengelakkan penukaran rentetan.

Penyelesaian

Anda boleh menggunakan float32 值转换回 float64 untuk pengesahan sahaja.

Untuk menyemak sama ada nilai yang ditukar mewakili nilai yang sama, cuma bandingkan dengan nilai asal (input). Pulangan sahaja ok bool 信息(而不是 error) juga memadai/idiomatik:

func convert(input float64) (output float32, ok bool) {
    output = float32(input)
    ok = float64(output) == input
    return
}

(Nota: Kes tepi seperti nan tidak disemak.)

Uji:

fmt.println(convert(1))
fmt.println(convert(1.5))
fmt.println(convert(0.123456789))
fmt.println(convert(math.maxfloat32))

Output (cuba di pergi taman permainan):

1 true
1.5 true
0.12345679 false
3.4028235e+38 true

Perhatikan bahawa ini biasanya akan memberi ok = false 结果,因为 float32 的精度小于 float64 walaupun nilai yang ditukar mungkin sangat hampir dengan input.

Jadi dalam amalan, adalah lebih berguna untuk menyemak perbezaan dalam nilai yang ditukar. Penyelesaian yang dicadangkan anda menyemak perbezaan mutlak, yang tidak begitu berguna: cth. 1000000.11000000 是非常接近的数字,即使差异是 0.10.00010.00011 的差异要小得多:0.00001, tetapi perbezaannya jauh lebih besar berbanding dengan nombor.

Jadi anda harus menyemak perbezaan relatif, contohnya:

func convert(input float64) (output float32, ok bool) {
    const maxreldiff = 1e-8

    output = float32(input)
    diff := math.abs(float64(output) - input)
    ok = diff <= math.abs(input)*maxreldiff

    return
}

Uji:

fmt.println(convert(1))
fmt.println(convert(1.5))
fmt.println(convert(1e20))
fmt.println(convert(math.pi))
fmt.println(convert(0.123456789))
fmt.println(convert(math.maxfloat32))

Output (cuba di pergi taman permainan):

1 true
1.5 true
1e+20 false
3.1415927 false
0.12345679 false
3.4028235e+38 true

Atas ialah kandungan terperinci Pergi: Bagaimana untuk menyemak kehilangan ketepatan apabila menukar float64 kepada float32. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam