Estou confuso sobre por que nos preocupamos com diferentes representações para zero positivo e negativo.
Lembro-me vagamente das alegações de leitura de que ter uma representação zero negativa é extremamente importante na programação que envolve números complexos. Eu nunca tive a oportunidade de escrever código que envolva números complexos, por isso estou um pouco confuso sobre por que esse seria o caso.
O artigo da Wikipedia sobre o conceito não é especialmente útil; só faz afirmações vagas sobre zero assinado, tornando certas operações matemáticas mais simples em ponto flutuante, se bem entendi. Esta resposta lista algumas funções que se comportam de maneira diferente, e talvez algo possa ser inferido nos exemplos se você estiver familiarizado com o modo como elas podem ser usadas. (Embora o exemplo particular das raízes quadradas complexas pareça totalmente errado, já que os dois números são matematicamente equivalentes, a menos que eu tenha um mal-entendido.) Mas não consegui encontrar uma declaração clara do tipo de problema que você enfrentaria se não estivesse lá. Os recursos mais matemáticos que pude encontrar afirmam que não há distinção entre os dois de uma perspectiva matemática, e o artigo da Wikipedia parece sugerir que isso raramente é visto fora da computação, além de descrever limites.
Então, por que um zero negativo é valioso na computação? Tenho certeza de que estou perdendo alguma coisa.
fonte
sqrt(-1+0i) = i
esqrt(-1-0i) = -i
, embora esteja vestido com a sintaxe apropriada para alguma linguagem de programação, acredito. Vou editar para ficar mais claro.Respostas:
Você deve ter em mente que, na aritmética da FPU, 0 não necessariamente significa exatamente zero, mas também valor muito pequeno para ser representado usando o tipo de dados fornecido, por exemplo,
a é muito pequeno para ser representado corretamente por float (32 bits); portanto, é "arredondado" para -0.
Agora, digamos que nosso cálculo continue:
Como a é float, resultará em -infinity, que está bem longe da resposta correta de -1000000000000000000.0.
Agora vamos calcular b se não houver -0 (então a é arredondado para +0):
O resultado está errado novamente por causa do arredondamento, mas agora está "mais errado" - não apenas numericamente, mas mais importante por causa de sinais diferentes (o resultado da computação é + infinito, o resultado correto é -1000000000000000000.0).
Você ainda pode dizer que isso realmente não importa, pois ambos estão errados. O importante é que existem muitas aplicações numéricas em que o resultado mais importante da computação é o sinal - por exemplo, ao decidir virar à esquerda ou à direita na encruzilhada usando algum algoritmo de aprendizado de máquina, você pode interpretar o valor positivo => girar esquerda, valor negativo => vire à direita, a "magnitude" real do valor é apenas "coeficiente de confiança".
fonte
+inf
e-inf
em operação normal estão com erros.+inf
e-inf
. Se o seu programa causa um fluxo insuficiente de ponto flutuante, esse é o erro e o que acontece depois não é tão interessante, imho. Ainda faltam exemplos práticos nos quais -0 é útil.Primeiro, como você cria um -0? Existem duas maneiras: (1) faça uma operação de ponto flutuante em que o resultado matemático é negativo, mas tão próximo de zero que é arredondado para zero e não para um número diferente de zero. Esse cálculo dará um -0. (b) Certas operações que envolvem zeros: multiplique um zero positivo por um número negativo ou divida um zero positivo por um número negativo ou negue um zero positivo.
Ter um zero negativo simplifica um pouco a multiplicação e a divisão, o sinal de x * y ou x / y é sempre o sinal de x, exclusivo ou o sinal de y. Sem zero negativo, haveria uma verificação extra para substituir -0 por +0.
Existem algumas situações muito raras em que é útil. Você pode verificar se o resultado de uma multiplicação ou divisão é matematicamente maior que ou menor que zero, mesmo se houver um fluxo insuficiente (desde que você saiba que o resultado não é um zero matemático). Não me lembro de ter escrito código onde faz diferença.
Os compiladores de otimização odeiam -0. Por exemplo, você não pode substituir x + 0,0 por x, porque o resultado não deve ser x se x for -0,0. Você não pode substituir x * 0,0 por 0,0, porque o resultado deve ser -0,0 se x <0 ou x for -0,0.
fonte
-5
e5
entrandofmod()
. É muito chato para o meu caso de uso.C # Duplo em conformidade com IEEE 754
impressões:
na verdade, para explicar um pouco ...
Isso significa algo muito mais próximo de d =
The Limit of x as x approaches 0-
ouThe Limit of x as x approaches 0 from the negatives
.Para abordar o comentário de Philipp ...
Basicamente zero negativo significa subfluxo.
Há muito pouco uso prático para zero negativo, se houver ...
por exemplo, este código (novamente C #):
produz este resultado:
Para explicar informalmente, todos os valores especiais que um ponto flutuante IEEE 754 pode ter (infinito positivo, infinito negativo, NAN, -0,0) não têm significado no sentido prático. Eles não podem representar nenhum valor físico ou qualquer valor que faça sentido no cálculo do "mundo real". O que eles querem dizer é basicamente isso:
sqrt(-7)
ou não possui um limite como0/0
ou comoPositiveInfinity/PositiveInfinity
fonte
A questão de como isso se relaciona com os cálculos de números complexos realmente está no cerne do motivo pelo qual ambos +0 e -0 existem no ponto flutuante. Se você estuda Análise Complexa, descobre rapidamente que funções contínuas de Complex para Complex geralmente não podem ser tratadas como 'valor único', a menos que se adote a 'ficção educada' de que as saídas formam o que é conhecido como 'superfície de Riemann'. Por exemplo, o logaritmo complexo atribui cada entrada infinitamente a muitas saídas; quando você os conecta para formar uma saída contínua, você acaba com todas as peças reais formando uma superfície de 'saca-rolhas infinito' ao redor da origem. Uma curva contínua que atravessa o eixo real 'para baixo do lado imaginário positivo' e outra curva que 'envolve o polo' e atravessa o eixo real '
Agora aplique isso a um programa numérico que calcula usando ponto flutuante complexo. A ação executada após um determinado cálculo pode ser muito diferente, dependendo de qual 'planilha' o programa está atualmente 'ativado', e o sinal do último resultado calculado provavelmente indica qual 'planilha'. Agora, suponha que o resultado seja zero? Lembre-se, aqui 'zero' realmente significa 'pequeno demais para representar corretamente'. Porém, se o cálculo puder arranjar para preservar o sinal (ou seja, lembre-se de qual 'planilha') quando o resultado for zero, o código poderá verificar o sinal e executar a ação correta, mesmo nessa situação.
fonte
O motivo é mais simples que o normal
É claro que existem muitos hacks que parecem realmente legais e são úteis (como arredondar para
-0.0
ou+0.0
assumir que temos uma representação de int assinado com um sinal de menos / mais no início (eu sei que isso é resolvido pelo código binário U2 em números inteiros geralmente, mas assumem uma representação menos complexa de double):E se houver um número negativo?
Ok, simples assim. Então, vamos representar 0:
Tudo bem também. Mas que tal
1 000
? Tem que ser um número proibido? Melhor não.Então, vamos assumir que existem dois tipos de zero:
Bem, isso simplificará nossos cálculos e, com sorte, fornecerá alguns recursos adicionais. Portanto, o
+0
e-0
está vindo apenas de questões de representação binária.fonte