¿Por qué es importante el cero negativo?

58

Estoy confundido acerca de por qué nos importan las diferentes representaciones del cero positivo y negativo.

Recuerdo vagamente las afirmaciones de lectura de que tener una representación negativa de cero es extremadamente importante en la programación que involucra números complejos. Nunca tuve la oportunidad de escribir código con números complejos, así que estoy un poco desconcertado acerca de por qué este sería el caso.

artículo de Wikipedia sobre el concepto no es especialmente útil; solo hace declaraciones vagas sobre el cero firmado, lo que hace que ciertas operaciones matemáticas sean más simples en coma flotante, si lo comprendo correctamente. Esta respuesta enumera un par de funciones que se comportan de manera diferente, y tal vez se pueda deducir algo de los ejemplos si está familiarizado con cómo podrían ser utilizados. (Aunque, el ejemplo particular de las raíces cuadradas complejas parece totalmente incorrecto , ya que los dos números son matemáticamente equivalentes, a menos que tenga un malentendido). Pero no he podido encontrar una declaración clara del tipo de problemas que se metería si no estuviera allí. Los recursos más matemáticos que he podido encontrar indican que no hay distinción entre los dos desde una perspectiva matemática, y el artículo de Wikipedia parece sugerir que esto rara vez se ve fuera de la computación, aparte de describir los límites.

Entonces, ¿por qué un cero negativo es valioso en la computación? Estoy seguro de que me estoy perdiendo algo.

    
pregunta jpmc26 01.05.2015 - 04:10

5 respuestas

63

Debe tener en cuenta que, en aritmética FPU, 0 no necesariamente tiene que significar exactamente cero, sino que también es un valor demasiado pequeño para representarlo usando el tipo de datos dado, por ejemplo.

a = -1 / 1000000000000000000.0

a es demasiado pequeño para ser representado correctamente por float (32 bits), por lo que se "redondea" a -0.

Ahora, digamos que nuestro cálculo continúa:

b = 1 / a

Debido a que a es flotante, resultará en un infinito que está muy lejos de la respuesta correcta de -1000000000000000000.0

Ahora calculemos b si no hay -0 (entonces a se redondea a +0):

b = 1 / +0
b = +infinity

El resultado vuelve a ser incorrecto debido al redondeo, pero ahora es "más incorrecto", no solo numéricamente, sino más importante debido a un signo diferente (el resultado del cálculo es + infinito, el resultado correcto es -1000000000000000000.0).

Aún puedes decir que realmente no importa ya que ambos están equivocados. Lo importante es que hay muchas aplicaciones numéricas donde el resultado más importante de la computación es el signo, por ejemplo, al decidir si girar a la izquierda o a la derecha en la encrucijada utilizando algún algoritmo de aprendizaje automático, puede interpretar un valor positivo = > gire a la izquierda, valor negativo = > gire a la derecha, la "magnitud" real del valor es simplemente "coeficiente de confianza".

    
respondido por el qbd 01.05.2015 - 17:30
8

Primero, ¿cómo creas un -0? Hay dos formas: (1) hacer una operación de punto flotante donde el resultado matemático es negativo, pero tan cerca de cero que se redondea a cero y no a un número distinto de cero. Ese cálculo dará un -0. (b) Ciertas operaciones que involucran ceros: multiplique un cero positivo por un número negativo, o divida un cero positivo por un número negativo, o niegue un cero positivo.

Tener un cero negativo simplifica un poco la multiplicación y la división, el signo de x * y o x / y es siempre el signo de x, exclusivo o el signo de y. Sin el cero negativo, tendría que haber alguna verificación adicional para reemplazar -0 con +0.

Hay algunas situaciones muy raras donde es útil. Puede verificar si el resultado de una multiplicación o división es matemáticamente mayor o menor que cero, incluso si hay un desbordamiento (siempre que sepa que el resultado no es un cero matemático). No recuerdo haber escrito nunca un código donde haga una diferencia.

La optimización de compiladores odia -0. Por ejemplo, no puede reemplazar x + 0.0 con x, porque el resultado no debería ser x si x es -0.0. No puede reemplazar x * 0.0 con 0.0, porque el resultado debería ser -0.0 si x < 0 o x es -0.0.

    
respondido por el gnasher729 02.05.2015 - 18:41
6

C # doble que cumple con IEEE 754

    double a = 3.0;
    double b = 0.0;
    double c = -0.0;

    Console.WriteLine(a / b);
    Console.WriteLine(a / c);

impresiones:

Infinity
-Infinity

en realidad para explicar un poco ...

Double d = -0.0; 

Esto significa algo mucho más cercano a d = The Limit of x as x approaches 0- o The Limit of x as x approaches 0 from the negatives .

Para abordar el comentario de Philipp ...

Básicamente, cero negativo significa subdesbordamiento.

Hay muy poco uso práctico para el cero negativo, si existe ...

por ejemplo, este código (nuevamente C #):

double a = -0.0;
double b = 0.0;

Console.WriteLine(a.Equals(b));
Console.WriteLine(a==b);
Console.WriteLine(Math.Sign(a));

produce este resultado:

True
True
0

Para explicar informalmente, todos los valores especiales que puede tener un punto flotante IEEE 754 (infinito positivo, infinito negativo, NAN, -0.0) no tienen significado en el sentido práctico. No pueden representar ningún valor físico ni ningún valor que tenga sentido en el cálculo del "mundo real". Lo que quieren decir es básicamente esto:

  • infinito positivo significa un desbordamiento en el extremo positivo que un punto flotante puede representar
  • infinito negativo significa un desbordamiento en el extremo positivo que un punto flotante puede representar
  • cero negativo significa un subdesbordamiento y los operandos tenían signos opuestos
  • cero positivo puede significar un subflujo y los operandos tenían el mismo signo
  • NAN significa que su cálculo es indefinidamente complaciente, como sqrt(-7) , o no tiene un límite como 0/0 o como PositiveInfinity/PositiveInfinity
respondido por el AK_ 01.05.2015 - 16:57
5

La pregunta sobre cómo se relaciona esto con los cálculos de números complejos realmente llega a la esencia de por qué tanto +0 y -0 existen en punto flotante. Si estudia el Análisis complejo en absoluto, rápidamente descubre que las funciones continuas de Complejo a Complejo generalmente no pueden tratarse como 'de valor único' a menos que uno adopte la 'ficción cortés' de que las salidas forman lo que se conoce como una 'superficie de Riemann'. Por ejemplo, el logaritmo complejo asigna a cada entrada un número infinito de salidas; cuando los 'conectas' para formar una salida continua, terminas con todas las partes reales formando una superficie de 'sacacorchos infinito' alrededor del origen. Una curva continua que cruza el eje real 'hacia abajo desde el lado positivo-imaginario' y otra curva que 'gira alrededor del polo' y cruza el eje real 'hacia arriba desde el lado negativo-imaginario' tomará diferentes valores en el eje real porque Pasan sobre diferentes "hojas" de la superficie de Riemann.

Ahora aplique eso a un programa numérico que calcula usando un punto flotante complejo. La acción realizada después de un cálculo dado puede ser muy diferente dependiendo de la "hoja" en la que el programa está actualmente "encendido", y el signo del último resultado calculado probablemente le indique qué "hoja". Ahora supongamos que ese resultado fue cero? Recuerde, aquí 'cero' realmente significa 'demasiado pequeño para representarlo correctamente'. Pero si el cálculo podría organizar -proteger el signo- (es decir, recordar qué 'hoja') cuando el resultado es cero, entonces el código puede verificar el signo y realizar la acción correcta incluso en esta situación.

    
respondido por el PJM 26.02.2016 - 16:04
1

El motivo es más simple de lo habitual

Por supuesto, hay muchos hacks que se ven muy bien y son útiles (como redondear a -0.0 o +0.0 , pero supongamos que tenemos una representación de int firmado con un signo menos) / signo más al principio (sé que esto se resuelve con el código binario U2 en enteros generalmente, pero supongo que es una representación menos compleja del doble):

0 111 = 7
^ sign

¿Qué pasa si hay un número negativo?

1 111 = -7

Bien, así de simple. Así que vamos a representar 0:

0 000 = 0

Eso también está bien. Pero ¿qué pasa con 1 000 ? ¿Tiene que ser un número prohibido? Mejor no.

Supongamos que hay dos tipos de cero:

0 000 = +0
1 000 = -0

Bueno, eso simplificará nuestros cálculos y, afortunadamente, ofrecerá algunas funciones adicionales de redondeo. Entonces, +0 y -0 provienen solo de problemas de representación binaria.

    
respondido por el Dawid Pura 01.05.2015 - 18:07

Lea otras preguntas en las etiquetas