long lenguaje float c floating-point unsigned

lenguaje - unsigned float c++



¿Por qué C no tiene flotadores sin signo? (10)

Una raíz cuadrada definitivamente nunca devolverá un número negativo. También hay otros lugares donde un valor flotante negativo no tiene significado. Candidato perfecto para una carroza sin signo.

C99 admite números complejos y un tipo genérico de sqrt, por lo que sqrt( 1.0 * I) será negativo.

Los comentadores resaltaron un ligero comentario anterior, en el sentido de que me refería a la macro sqrt type-generic en lugar de a la función, y devolverá un valor escalar de punto flotante mediante el truncamiento del complejo a su componente real:

#include <complex.h> #include <tgmath.h> int main () { complex double a = 1.0 + 1.0 * I; double f = sqrt(a); return 0; }

También contiene un fart cerebral, ya que la parte real del sqrt de cualquier número complejo es positiva o cero, y sqrt (1.0 * I) es sqrt (0.5) + sqrt (0.5) * I not -1.0.

Lo sé, la pregunta parece ser extraña. Los programadores a veces piensan demasiado. Por favor, lea en ...

En CI usa mucho los enteros con y sin signo. Me gusta el hecho de que el compilador me advierta si hago cosas como asignar un entero con signo a una variable sin signo. Recibo advertencias si comparo firmado con enteros sin signo y mucho más.

Me gustan estas advertencias Me ayudan a mantener mi código correcto.

¿Por qué no tenemos el mismo lujo para las carrozas? Una raíz cuadrada definitivamente nunca devolverá un número negativo. También hay otros lugares donde un valor flotante negativo no tiene significado. Candidato perfecto para una carroza sin signo.

Por cierto, no estoy muy interesado en la precisión adicional que podría obtener al quitar el letrero de las carrozas. Estoy muy contento con los float como son ahora. Me gustaría marcar un flotador como sin signo a veces y obtener el mismo tipo de advertencias que obtengo con enteros.

No conozco ningún lenguaje de programación que admita números de punto flotante sin signo.

¿Alguna idea de por qué no existen?

EDITAR: Sé que la FPU x87 no tiene instrucciones para tratar con flotadores sin signo. Solo usemos las instrucciones de flotación firmadas. El mal uso (por ejemplo, ir por debajo de cero) podría considerarse un comportamiento indefinido de la misma manera que el desbordamiento de enteros con signo no está definido.


(Como un aparte, Perl 6 te permite escribir

subset Nonnegative::Float of Float where { $_ >= 0 };

y luego puedes usar Nonnegative::Float como lo harías con cualquier otro tipo).

No hay soporte de hardware para operaciones de punto flotante sin signo, por lo que C no lo ofrece. C está diseñado principalmente para ser "ensamblado portátil", es decir, lo más cerca posible del metal sin estar atado a una plataforma específica.

[editar]

C es como ensamblaje: lo que ves es exactamente lo que obtienes. Un implícito "comprobaré que este flotador no sea negativo para usted" va en contra de su filosofía de diseño. Si realmente lo desea, puede agregar assert(x >= 0) o similar, pero debe hacerlo explícitamente.


Creo que Treb está en el camino correcto. Es más importante para los enteros que tenga un tipo sin signo correspondiente. Esos son los que se utilizan en el cambio de bits y se utilizan en mapas de bits . Un poco de señal se mete en el camino. Por ejemplo, al desplazar a la derecha un valor negativo, el valor resultante es la implementación definida en C ++. Hacer eso con un entero sin signo o desbordamiento tiene una semántica perfectamente definida porque no hay tal bit en el camino.

Por lo tanto, para enteros al menos, la necesidad de un tipo independiente sin signo es más fuerte que simplemente dar advertencias. Todos los puntos anteriores no necesitan ser considerados para carrozas. Entonces, creo que no existe una necesidad real de soporte de hardware para ellos, y C ya no los apoyará en ese punto.


Creo que la int sin firmar se creó debido a la necesidad de un margen de valor mayor que el int. Firmado podría ofrecer.

Un flotador tiene un margen mucho más grande, por lo que nunca hubo una necesidad ''física'' de un flotante sin signo. Y como usted mismo señala en su pregunta, la precisión adicional de 1 bit no es nada para matar.

Editar: Después de leer la respuesta de Brian R. Bondy , tengo que modificar mi respuesta: definitivamente tiene razón en que las CPU subyacentes no tenían operaciones de flotación sin signo. Sin embargo, mantengo mi creencia de que esta fue una decisión de diseño basada en las razones que expuse anteriormente ;-)


Creo que la razón principal es que los flotadores sin signo tendrían usos realmente limitados en comparación con los sin signo. No me creo el argumento de que sea porque el hardware no lo admite. Los procesadores antiguos no tenían capacidades de coma flotante en absoluto, todo estaba emulado en el software. Si los flotadores sin signo fueran útiles, se habrían implementado primero en el software y el hardware habría seguido su ejemplo.


Hay una diferencia significativa entre los enteros con signo y sin signo en C / C ++:

value >> shift

los valores firmados dejan el bit superior sin cambios (signo extender), los valores sin signo borran el bit superior.

La razón por la que no hay flotación sin signo es que rápidamente se encuentra con todo tipo de problemas si no hay valores negativos. Considera esto:

float a = 2.0f, b = 10.0f, c; c = a - b;

¿Qué valor tiene c? -8. Pero qué significa eso en un sistema sin números negativos. FLOAT_MAX - 8 tal vez? En realidad, eso no funciona, ya que FLOAT_MAX - 8 es FLOAT_MAX debido a los efectos de precisión, por lo que las cosas son aún más complicadas. ¿Y si fuera parte de una expresión más compleja?

float a = 2.0f, b = 10.0f, c = 20.0f, d = 3.14159f, e; e = (a - b) / d + c;

Esto no es un problema para enteros debido a la naturaleza del sistema de complemento de 2.

También considere funciones matemáticas estándar: sin, cos y tan sólo funcionarían para la mitad de sus valores de entrada, no podría encontrar el registro de valores <1, no podría resolver ecuaciones cuadráticas: x = (-b +/- raíz ( bb - 4.ac)) / 2.a, y así sucesivamente. De hecho, probablemente no funcionaría para ninguna función compleja, ya que tienden a implementarse como aproximaciones polinomiales que utilizarían valores negativos en alguna parte.

Entonces, las carrozas sin signo son bastante inútiles.

Pero eso no quiere decir que una clase cuyo rango verifique los valores flotantes no sea útil, es posible que desee fijar los valores a un rango dado, por ejemplo, cálculos RGB.


Los tipos enteros sin signo en C se definen de tal manera que obedecen las reglas de un anillo algebraico abstracto. Por ejemplo, para cualquier valor X e Y, agregar XY a Y arrojará X. Se garantiza que los tipos enteros sin signo obedecerán a estas reglas en todos los casos que no impliquen la conversión hacia o desde cualquier otro tipo numérico [o tipos sin firmar de diferentes tamaños] , y esa garantía es una de las características más importantes de dichos tipos. En algunos casos, vale la pena renunciar a la capacidad de representar números negativos a cambio de las garantías adicionales que solo pueden proporcionar los tipos sin firmar. Los tipos de coma flotante, ya sean firmados o no, no pueden cumplir con todas las reglas de un anillo algebraico [por ejemplo, no pueden garantizar que X + YY sea igual a X], y de hecho IEEE ni siquiera les permite cumplir con las reglas de un clase de equivalencia [requiriendo que ciertos valores se comparen desigualmente consigo mismos]. No creo que un tipo de punto flotante "sin firmar" pueda cumplir con ningún axioma que un tipo de coma flotante común no pueda, por lo que no estoy seguro de qué ventajas ofrecería.


Por qué C ++ no tiene soporte para flotantes sin signo se debe a que no hay operaciones equivalentes de código de máquina para que se ejecute la CPU. Entonces sería muy ineficiente apoyarlo.

Si C ++ sí lo admitía, a veces estarías usando un flotador sin firmar y sin darte cuenta de que tu actuación acaba de ser eliminada. Si C ++ lo admite, será necesario verificar cada operación de punto flotante para ver si está firmado o no. Y para los programas que hacen millones de operaciones de punto flotante, esto no es aceptable.

Entonces la pregunta sería por qué los implementadores de hardware no lo admiten. Y creo que la respuesta a eso es que no había un estándar de flotación sin signo definido originalmente. Dado que los idiomas prefieren ser compatibles con versiones anteriores, incluso si se tratara de idiomas añadidos, no podrían utilizarse. Para ver la especificación del punto flotante, debe mirar el punto flotante estándar IEEE 754 .

Puede moverse sin tener un tipo de punto flotante sin signo creando una clase flotante sin signo que encapsula un flotante o doble y lanza advertencias si intenta pasar un número negativo. Esto es menos eficiente, pero probablemente si no los usa intensamente no le importará esa ligera pérdida de rendimiento.

Definitivamente veo la utilidad de tener un flotador sin signo. Pero C / C ++ tiende a elegir la eficiencia que funciona mejor para todos por encima de la seguridad.


Sospecho que se debe a que los procesadores subyacentes a los que apuntan los compiladores C no tienen una buena forma de tratar con los números flotantes sin signo.


Supongo que depende de que las especificaciones de los puntos flotantes IEEE solo estén firmadas y que la mayoría de los lenguajes de programación las usen.

articla de wikipedia en los números de punto flotante de ieee

Editar: Además, como señalaron otros, la mayoría del hardware no admite flotantes no negativos, por lo que el tipo normal de flotadores es más eficiente ya que hay soporte de hardware.