Estoy confundido acerca de por qué nos importan las diferentes representaciones de 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 he tenido la oportunidad de escribir código que involucre números complejos, así que estoy un poco desconcertado sobre por qué este sería el caso.
El artículo de Wikipedia sobre el concepto no es especialmente útil; solo hace vagas afirmaciones sobre el cero con signo, lo que simplifica ciertas operaciones matemáticas en coma flotante, si lo entiendo correctamente. Esta respuesta enumera un par de funciones que se comportan de manera diferente, y tal vez se podría inferir algo de los ejemplos si está familiarizado con cómo podrían usarse. (Aunque, el ejemplo particular de las raíces cuadradas complejas parece completamente 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 problema en el que te meterías 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 informática? Estoy seguro de que solo me falta algo.
fuente
sqrt(-1+0i) = i
ysqrt(-1-0i) = -i
, aunque está vestido con la sintaxis adecuada para algún lenguaje de programación, creo. Lo editaré para ser más claro.Respuestas:
Debe tener en cuenta que en la aritmética de FPU, 0 no necesariamente tiene que significar exactamente cero, sino que también tiene un valor demasiado pequeño para ser representado usando un tipo de datos dado, por ejemplo
a es demasiado pequeño para ser representado correctamente por flotante (32 bits), por lo que está "redondeado" a -0.
Ahora, digamos que nuestro cálculo continúa:
Debido a que a es flotante, dará como resultado un infinito que está bastante lejos de la respuesta correcta de -1000000000000000000.0
Ahora calculemos b si no hay -0 (entonces a se redondea a +0):
El resultado es incorrecto nuevamente debido al redondeo, pero ahora está "más equivocado", 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 se podría 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 del cálculo es el signo, por ejemplo, al decidir si girar a la izquierda o la derecha en la encrucijada utilizando algún algoritmo de aprendizaje automático, puede interpretar un valor positivo => girar izquierda, valor negativo => girar a la derecha, la "magnitud" real del valor es solo "coeficiente de confianza".
fuente
+inf
y-inf
en funcionamiento normal tienen errores.+inf
y-inf
. Si su programa causa un flujo inferior de coma flotante, ese es el error y lo que sucede después no es tan interesante, en mi opinión. Todavía nos faltan ejemplos prácticos en los que -0 es útil.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 cercano a 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 cero negativo, tendría que haber alguna verificación adicional para reemplazar -0 con +0.
Hay algunas situaciones muy raras en las que 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 flujo inferior (siempre y cuando sepa que el resultado no es un cero matemático). No recuerdo haber escrito un código que marque la diferencia.
Los compiladores optimizadores odian -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.
fuente
-5
y5
entrarfmod()
. Es bastante molesto para mi caso de uso.C # Double que cumple con IEEE 754
huellas dactilares:
en realidad para explicar un poco ...
Esto significa algo mucho más cercano a d =
The Limit of x as x approaches 0-
oThe Limit of x as x approaches 0 from the negatives
.Para abordar el comentario de Philipp ...
Básicamente cero negativo significa flujo inferior.
Hay muy poco uso práctico para el cero negativo, si lo hay ...
por ejemplo, este código (nuevamente C #):
produce este resultado:
Para explicar de manera informal, 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:
sqrt(-7)
, o no tiene un límite como0/0
o comoPositiveInfinity/PositiveInfinity
fuente
La pregunta acerca de cómo se relaciona esto con los cálculos de números complejos realmente llega al corazón de por qué tanto +0 como -0 existen en coma flotante. Si estudia el Análisis complejo, descubrirá rápidamente que las funciones continuas de Complejo a Complejo generalmente no pueden tratarse como 'de un solo valor' a menos que uno adopte la 'ficción cortés' de que las salidas forman lo que se conoce como 'superficie de Riemann'. Por ejemplo, el logaritmo complejo asigna a cada entrada infinitas salidas; cuando los 'conecta' para formar una salida continua, termina 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 'envuelve el polo' y cruza el eje real '
Ahora aplique eso a un programa numérico que calcule usando punto flotante complejo. La acción tomada después de un cálculo dado puede ser muy diferente dependiendo de la "hoja" en la que el programa se encuentra actualmente "encendido", y el signo del último resultado calculado probablemente le indica qué "hoja". Ahora supongamos que el resultado fue cero? Recuerde, aquí 'cero' realmente significa 'demasiado pequeño para representarlo correctamente'. Pero si el cálculo podría hacer arreglos para -conservar 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.
fuente
El motivo es más simple de lo habitual.
Por supuesto, hay muchos hacks que se ven realmente bien y son útiles (como redondear
-0.0
o+0.0
asumir que tenemos una representación de int firmado con un signo menos / más al principio (sé que se resuelve con el código binario U2) en enteros por lo general, pero suponga una representación menos compleja de doble):¿Qué pasa si hay un número negativo?
Bien, así de simple. Entonces representemos 0:
Eso también está bien. ¿Pero que pasa
1 000
? ¿Tiene que ser un número prohibido? Mejor no.Así que supongamos que hay dos tipos de cero:
Bueno, eso simplificará nuestros cálculos y, de forma fortuita, le dará algunas características adicionales de redondeo. Entonces,
+0
y-0
provienen solo de problemas de representación binaria.fuente