2010-05-14 18 views
38

Al aprender cómo se representan los números de coma flotante en las computadoras, me he topado con el término "valor de sesgo" que no entiendo del todo.¿Qué es un "valor de sesgo" de números de coma flotante?

El valor de polarización en números de coma flotante tiene que ver con la parte negativa y positiva de la parte exponente de un número de coma flotante.

El valor de polarización de un número de coma flotante es 127, lo que significa que 127 siempre se agrega a la parte exponente de un número de coma flotante. ¿Cómo ayuda esto a determinar si el exponente es negativo o positivo o no?

+0

Otra lectura interesante relacionada con esta pregunta es el artículo de esta Wikipedia: https://en.wikipedia.org/wiki/IEEE_754-1985 – nbro

Respuesta

43

En punto flotante de precisión simple, obtienes 8 bits para almacenar el exponente. En lugar de almacenarlo como un número de complemento de dos firmado, se decidió que sería más fácil agregar 127 solo al exponente (ya que el más bajo podría estar en 8 bits firmado es -127) y simplemente almacenarlo como un número sin firmar . Si el valor almacenado es mayor que el sesgo, eso significa que el valor del exponente es positivo, si es menor que el sesgo, es negativo, si es igual, es cero.

+0

Entonces, en formato IEEE, debido al sesgo de 127, si el campo del exponente es '00000000', ¿entonces esto significa que el exponente del número es -127? –

+0

@KennethWorden No, un valor de exponente de todos los ceros es especial y los números se interpretan como "desnormalizados" (y esto incluye 0 en sí). –

60

b0lt ya ha explicado cómo funciona el sesgo. En una suposición, quizás desee saber por qué usan una representación sesgada aquí, aunque virtualmente todas las computadoras modernas usan el complemento de dos esencialmente en cualquier otro lugar (e incluso las máquinas que no usan el complemento de dos, usan un complemento o señal -magnitud, no sesgo).

Uno de los objetivos de los estándares de punto flotante IEEE era que podía tratar los bits de un número de coma flotante como un entero (firmado) del mismo tamaño, y si los comparaba de esa manera, los valores se ordenarían en el mismo orden que los números de coma flotante que representaron.

Si utilizó una representación de complemento a dos para el exponente, un pequeño número positivo (es decir, con un exponente negativo) se vería como una gran número entero porque se establecería el segundo MSB. Al usar una representación de sesgo en su lugar, no se topa con eso: un exponente más pequeño en el número de punto flotante siempre se ve como un entero más pequeño.

FWIW, este es también el motivo por el cual los números de coma flotante se organizan primero con el signo, luego el exponente y finalmente el significado en los bits menos significativos. De esta forma, puede tomar números flotantes positivos, tratar esos bits como enteros, y ordenarlos. Cuando lo haga, el resultado tendrá los números de coma flotante en el orden correcto. Por ejemplo:

#include <vector> 
#include <algorithm> 
#include <iostream> 

int main() { 
    // some arbitrary floating point values 
    std::vector<double> vals = { 1e21, 1, 2.2, 2, 123, 1.1, 0.0001, 3, 17 }; 
    std::vector<long long> ivals; 

    // Take those floating point values, and treat the bits as integers: 
    for (auto &&v : vals) 
     ivals.push_back(*reinterpret_cast<long long *>(&v)); 

    // Sort them as integers: 
    std::sort(ivals.begin(), ivals.end()); 

    // Print out both the integers and the floating point value those bits represent: 
    for (auto &&i : ivals) 
     std::cout << i << "\t(" << *reinterpret_cast<double *>(&i) << ")\n"; 
} 

Cuando corremos esto, el resultado es idéntico:

4547007122018943789  (0.0001) 
4607182418800017408  (1) 
4607632778762754458  (1.1) 
4611686018427387904  (2) 
4612136378390124954  (2.2) 
4613937818241073152  (3) 
4625478292286210048  (17) 
4638355772470722560  (123) 
4921056587992461136  (1e+21) 

Como se puede ver, a pesar de que los clasificó como enteros, los números de punto flotante que esos bits representan también salir en el orden correcto

Esto tiene limitaciones con respecto a los números de coma flotante. Si bien todas las computadoras (no antiguas) concuerdan en la representación de los números positivos, hay tres representaciones que se han utilizado (bastante recientemente) para los números con signo: magnitud firmada, complemento de uno y complemento de dos.

Simplemente tratando los bits como un entero y comparando funcionará bien en una computadora que utiliza la representación de magnitud firmada para enteros. Para las computadoras que usan complemento de uno o complemento de dos, los números negativos se ordenarán en orden invertido. Como esta sigue siendo una regla simple, es bastante fácil escribir código que funcione con ella.Si cambiamos la llamada sort arriba para algo como esto:

std::sort(ivals.begin(), ivals.end(), 
    [](auto a, auto b) { if (a < 0.0 && b < 0.0) return b < a; return a < b; } 
); 

... A continuación, ordenar correctamente los números positivos y negativos. Por ejemplo, la entrada de:

std::vector<double> vals = { 1e21, 1, 2.2, 2, 123, 1.1, 0.0001, 3, 17, -0.001, -0.00101, -1e22 }; 

producirá un resultado de:

-4287162073302051438 (-1e+22) 
-4661071411077222194 (-0.00101) 
-4661117527937406468 (-0.001) 
4547007122018943789  (0.0001) 
4607182418800017408  (1) 
4607632778762754458  (1.1) 
4611686018427387904  (2) 
4612136378390124954  (2.2) 
4613937818241073152  (3) 
4625478292286210048  (17) 
4638355772470722560  (123) 
4921056587992461136  (1e+21) 
+0

Sí, también quería saber por qué. Esto responde eso. Muy interesante. Gracias. – mudge

+3

@JerryCoffin: +1 una respuesta excelente (en particular, la razón detrás del pedido dentro de los componentes del número fp). – legends2k

+0

@JerryCoffin No entiendo por qué los números de coma flotante se pueden tratar como números enteros ... Es decir, el mismo orden de bits tendrá un valor diferente para cada tipo de datos. ¿Puedes elaborar? – user1534664

13

añadiendo más detalles a las respuestas anteriores.

Para representar 0, infinity y NaN (Not-a-Number) en coma flotante, IEEE decidió usar valores de codificación especiales.

  • Si todos los bits del campo exponente están configurados en 0, entonces el número de coma flotante es 0.0.

  • Si todos los bits del campo exponente están establecidos en 1 y todos los bits de la parte de fracción son 0, entonces el número de coma flotante es infinito.

  • Si todos los bits del campo de exponente se ponen a 1 y todos los bits de la parte de fracción no son iguales a 0, entonces el número de punto flotante es NaN.

Así, en precisión simple que tiene 8 bits para representar el campo exponente y hay 2 valores especiales, así que básicamente tienen 256 - 2 = 254 los valores que se pueden representar en el exponente. Entonces, podemos representar efectivamente -126 a 127 en el exponente, es decir, 254 valores (126 + 127 + 1), se agrega 1 para 0.

Cuestiones relacionadas