Sé que los valores enteros 0
y -0
son esencialmente los mismos. Pero me pregunto si es posible diferenciarlos.
Por ejemplo, ¿cómo sé si se asignó una variable -0
?
bool IsNegative(int num)
{
// How ?
}
int num = -0;
int additinon = 5;
num += (IsNegative(num)) ? -addition : addition;
¿El valor -0
guardado en la memoria es exactamente igual que 0
?
c++
int
zero
negative-number
Filip Minx
fuente
fuente
int
se representa en complemento a 2 (con mucho, el más común)0
y-0
tienen representaciones bit a bit idénticas.int
. Consulte la codificación del complemento de unos .Respuestas:
Depende de la máquina a la que apuntes.
En una máquina que usa una representación de complemento a 2 para enteros, no hay diferencia a nivel de bit entre
0
y-0
(tienen la misma representación)Si su máquina usara el complemento de uno , definitivamente podría
Obviamente, estamos hablando de usar soporte nativo , los procesadores de la serie x86 tienen soporte nativo para la representación del complemento a dos de números con signo. Definitivamente es posible usar otras representaciones, pero probablemente sería menos eficiente y requeriría más instrucciones.
(Como también señaló JerryCoffin: incluso si el complemento de uno se ha considerado principalmente por razones históricas, las representaciones de magnitud con signo siguen siendo bastante comunes y tienen una representación separada para cero negativo y positivo)
fuente
0
y-0
son diferentes ? Honestamente, hubiera esperado que se comportara más como permitir representaciones de dos bits del mismo valor, y su programa puede usar la que le parezca.-0
, es decir, el resultado de aplicar el-
operador unario a la constante entera0
, sea una representación de cero negativo. Independientemente de la representación, el estándar nunca dice0
y-0
son valores matemáticamente diferentes, solo que puede haber un patrón de bits negativo-cero. Si lo hay, todavía representa el mismo valor numérico, 0.Para una
int
(en la representación casi universal de "complemento a 2") las representaciones de0
y-0
son lo mismo. (Pueden ser diferentes para otras representaciones numéricas, por ejemplo, punto flotante IEEE 754).fuente
Comencemos por representar 0 en el complemento de 2 (por supuesto que existen muchos otros sistemas y representaciones, aquí me refiero a este específico), asumiendo que el cero de 8 bits es:
Ahora volteemos todos los bits y agreguemos 1 para obtener el complemento de 2:
tenemos
0000 0000
, y esa es la representación de -0 también.Pero tenga en cuenta que en el complemento de 1, 0 con signo es 0000 0000, pero -0 es 1111 1111.
fuente
Decidí dejar esta respuesta ya que las implementaciones de C y C ++ generalmente están estrechamente relacionadas, pero de hecho no difiere del estándar C como pensé. El punto es que el estándar C ++ no especifica lo que sucede en casos como estos. También es relevante que las representaciones que no son de complemento a dos son extremadamente raras en el mundo real, y que incluso donde existen, a menudo ocultan la diferencia en muchos casos en lugar de exponerla como algo que alguien podría esperar descubrir fácilmente.
El comportamiento de los ceros negativos en las representaciones enteras en las que existen no está tan rigurosamente definido en el estándar C ++ como lo está en el estándar C. Sin embargo, sí cita la norma C (ISO / IEC 9899: 1999) como referencia normativa en el nivel superior [1.2].
En el estándar C [6.2.6.2], un cero negativo solo puede ser el resultado de operaciones bit a bit o de operaciones en las que ya está presente un cero negativo (por ejemplo, multiplicar o dividir un cero negativo por un valor, o agregar un cero negativo a cero): la aplicación del operador menos unario a un valor de un cero normal, como en su ejemplo, está garantizado para dar como resultado un cero normal.
Incluso en los casos que pueden generar un cero negativo, no hay garantía de que lo harán, incluso en un sistema que admite cero negativo:
Por tanto, podemos concluir: no, no existe una forma fiable de detectar este caso. Incluso si no fuera por el hecho de que las representaciones de complemento no a dos son muy poco comunes en los sistemas informáticos modernos.
El estándar C ++, por su parte, no menciona el término "cero negativo" y tiene muy poca discusión sobre los detalles de la magnitud con signo y las representaciones de complemento a uno, excepto para notar [3.9.1 párrafo 7] que están permitidos.
fuente
_Bool
o_Complex
o inicializadores designados o literales compuestos en C ++). El estándar C ++ sabe cómo incorporar el estándar C cuando quiere, por ejemplo, [basic.fundamental] / p3: "Los tipos enteros con signo y sin signo deben satisfacer las restricciones dadas en el estándar C, sección 5.2.4.2.1".Si su máquina tiene representaciones distintas para
-0
y+0
,memcmp
podrá distinguirlas.Si hay bits de relleno, es posible que también haya varias representaciones para valores distintos de cero.
fuente
En la especificación del lenguaje C ++, no existe un int como cero negativo .
El único significado que tienen esas dos palabras es el operador unario
-
aplicado0
, al igual que tres más cinco es solo el operador binario+
aplicado a3
y5
.Si hubiera un cero negativo distinto , el complemento a dos (la representación más común de tipos enteros) sería una representación insuficiente para las implementaciones de C ++, ya que no hay forma de representar dos formas de cero.
Por el contrario, los puntos flotantes (siguiendo IEEE) tienen ceros positivos y negativos separados. Se pueden distinguir, por ejemplo, al dividir 1 por ellos. El cero positivo produce infinito positivo; cero negativo produce infinito negativo.
Sin embargo, si hay diferentes representaciones de memoria del int 0 (o cualquier int, o cualquier otro valor de cualquier otro tipo), puede usar
memcmp
para descubrir que:Por supuesto, si esto sucediera, fuera de las operaciones de memoria directa, los dos valores seguirían funcionando exactamente de la misma manera.
fuente
Para simplificar, lo encontré más fácil de visualizar.
El tipo int (_32) se almacena con 32 bits . 32 bits significa 2 ^ 32 = 4294967296 valores únicos . Así:
el rango de datos int sin signo es de 0 a 4,294,967,295
En caso de valores negativos, depende de cómo se almacenen. En caso
En el caso del complemento a uno, existe el valor -0.
fuente
int
no se almacena en 32 bits son más populares que las plataformas con complemento de uno en la actualidad.