Отличительный знак нуля: -float64 (0) от float64 (0) в Go - PullRequest
4 голосов
/ 29 августа 2011

Я хочу сериализовать число с плавающей запятой таким образом, чтобы информация знака не терялась. В частности, я бы хотел отличить отрицательный ноль IEEE-754 от обычного ноля.

Спецификация языка говорит

Результат деления с плавающей запятой на ноль не указан вне стандарта IEEE-754; возникновение паники во время выполнения зависит от реализации.

, что говорит о том, что я не могу сделать

n == 0 && (float64(1) / n) < 0

и я попытался math.Copysign и math.Signbit, что говорит

func Signbit(x float64) bool

Signbit возвращает true, если x отрицательный или отрицательный ноль.

но

n == 0 && math.Signbit(n)

не похоже на

n := -float64(0)

Есть идеи?

EDIT:

Я подал выпуск 2196 , чтобы отследить то, что, по моему мнению, является запутанным отличием

nz := -float64(0)

и

pz := float64(0)
nz := -pz

как предложено peterSO.

Ответы [ 2 ]

3 голосов
/ 29 августа 2011
package main

import (
    "fmt"
    "math"
)

func main() {
    pz := float64(0)
    nz := -pz
    fmt.Println(pz, math.Signbit(pz), nz, math.Signbit(nz))
    if n := nz; n == 0 && math.Signbit(n) {
        fmt.Println("n is negative zero:", n)
    }
}

Выход:

0 false -0 true
n is negative zero: -0
3 голосов
/ 29 августа 2011

Мне не удалось заставить игровую площадку (http://golang.org/doc/play/) генерировать -0 из буквального ввода его в исходном коде;Я бы предположил, что компилятор преобразует его в 0.

Однако я мог бы сгенерировать -0 так:

fmt.Println(0);
fmt.Println(-0);
hmm := -1 / math.Inf(1);
fmt.Println(math.Signbit(hmm));
fmt.Println(hmm);

Печать:

0
0
true
-0
...