Para mayor claridad, si estoy usando un lenguaje que implementa flotadores IEE 754 y declaro:
float f0 = 0.f;
float f1 = 1.f;
... y luego imprimirlos de nuevo, obtendré 0.0000 y 1.0000, exactamente.
Pero IEEE 754 no es capaz de representar todos los números a lo largo de la línea real. Cerca de cero, las 'brechas' son pequeñas; A medida que te alejas, las brechas se hacen más grandes.
Entonces, mi pregunta es: para un flotante IEEE 754, ¿cuál es el primer entero (más cercano a cero) que no puede representarse exactamente? Solo estoy realmente preocupado por los flotantes de 32 bits por ahora, aunque me interesaría escuchar la respuesta de 64 bits si alguien me lo da.
Pensé que esto sería tan simple como calcular 2 bits_de_mantissa y agregar 1, donde bits_de_mantissa es cuántos bits expone el estándar. Hice esto para flotantes de 32 bits en mi máquina (MSVC ++, Win64), y parecía estar bien, sin embargo.
fuente
Respuestas:
2 bits de mantisa + 1 + 1
El +1 en el exponente (mantissa bits + 1) se debe a que, si la mantisa contiene
abcdef...
el número que representa1.abcdef... × 2^e
, en realidad proporciona un bit de precisión adicional implícito.Por lo tanto, el primer entero que no se puede representar con precisión y se redondeará es:
For
float
, 16,777,217 (2 24 + 1).Para
double
, 9,007,199,254,740,993 (2 53 + 1).fuente
float
y lo puse igual a 16.777.217. Pero cuando lo imprimí usandocout
, resultó en 16,777,216. Estoy usandoC++
. ¿Por qué no puedo obtener 16,777,217?(1 << std::numeric_limits<float>::digits) + 1
, y en C(1 << FLT_MANT_DIG) + 1
,. Lo primero es bueno porque puede ser parte de una plantilla. No agregue el +1 si solo desea el número entero representable más grande.El valor más grande representable por un entero de n bits es 2 n -1. Como se señaló anteriormente, a
float
tiene 24 bits de precisión en el significado que parece implicar que 2 24 no encajaría.Sin embargo .
Las potencias de 2 dentro del rango del exponente son exactamente representables como 1.0 × 2 n , por lo que 2 24 puede caber y, en consecuencia, el primer entero no representable para
float
2 24 +1. Como se señaló anteriormente. De nuevo.fuente