2009-04-17 24 views
17

¿Puedo comparar un número de coma flotante con un número entero?¿Puedo comparar y agregar un número de coma flotante a un número entero en C?

¿El flotante se comparará con los enteros del código?

float f;  // f has a saved predetermined floating-point value to it 
if (f >=100){__asm__reset...etc} 
podría

Además, me ...

float f; 
int x = 100; 
x+=f; 

Tengo que usar el valor de punto flotante f recibida desde un sistema de referencia de la posición para ajustar un valor de posición x que controla un PWM señal para corregir la actitud.

Respuesta

18

El primero funcionará bien. 100 se convertirán en un flotante, y IEE754 puede representar todos los enteros exactamente como flotadores, hasta aproximadamente 2 .

El segundo también funcionará, pero primero se convertirá en un número entero, por lo que perderá precisión (eso es inevitable si convierte los flotadores en enteros).

+0

Gracias, entonces eso significa que si f = 1.0162 sería int f == 1, entonces solo tendría que escalarlo, f * = 1000; tan int f == 1016 para mantener la precisión? – sevenboarder

+0

No puede representar todos los enteros exactamente como flotar. No con la mantisa de 24 bits de float. Si fuera el doble, sí, pero no flotar :) – Joey

+0

@Johannes, tienes razón, recuerdo mal una pregunta que respondí recientemente, actualicé para corregirla. – paxdiablo

0

Sí, funcionará bien. Específicamente, el int se convertirá en flotación para los propósitos de la conversión. En el segundo, deberás convertir a int pero, de lo contrario, debería estar bien.

1

LHS define la precisión, Por lo tanto, si su LHS es int y RHS está flotante, esto ocasiona pérdida de precisión.

también echar un vistazo a FP relacionados CFAQ

0

Sí, ya veces se va a hacer exactamente lo que esperas.

Como han señalado los demás, la comparación, por ejemplo, 1.0 == 1 funcionará, porque el número entero 1 es de tipo fundido a double (no float) antes de la comparación.

Sin embargo, otras comparaciones no pueden.

1

Sí, puede compararlos, puede hacer cálculos matemáticos sin demasiado respeto por cuál es cuál, en la mayoría de los casos. Pero solo la mayoría. El gran problema es que puedes verificar f<i etc., pero no debes verificar f==i. Un entero y un flotante que 'deberían' tener un valor idéntico no son necesariamente idénticos.

2

¿Se puede comparar un flotador y un número entero, seguro. Pero el problema con el que se encontrará es la precisión. En la mayoría de las implementaciones de C/C++, float e int tienen el mismo tamaño (4 bytes) y niveles de precisión muy diferentes. Ninguno de los tipos puede contener todos los valores del otro tipo. Dado que un tipo no se puede convertir al otro tipo sin pérdida de precisión y los tipos no se pueden comparar nativamente, hacer una comparación sin considerar otro tipo dará como resultado la pérdida de precisión en algunos escenarios.

Lo que puede hacer para evitar la pérdida de precisión es convertir ambos tipos a un tipo que tenga la precisión suficiente para representar todos los valores de float e int. En la mayoría de los sistemas, el doble hará exactamente eso.Así que la siguiente suele hacer una comparación con pocas pérdidas

float f = getSomeFloat(); 
int i = getSomeInt(); 
if ((double)i == (double)f) { 
    ... 
} 
+3

Creo que quieres "> =" (para que coincida con la pregunta original) y no "==". Probar la igualdad exacta de los números de coma flotante casi siempre es una mala idea. –

10

Puesto que usted ha identificado como familiarizados con las sutilezas de números de punto flotante, te remito a este papel fino por David Goldberg: What Every Computer Scientist Should Know About Floating-Point Arithmetic (reprint en Sol).

Después de que hayas asustado por eso, la realidad es que más del punto flotante en el tiempo es una gran ayuda para hacer los cálculos. Y los compiladores e idiomas modernos (incluida C) manejan las conversiones de manera sensata para que no tenga que preocuparse por ellas. A menos que hagas.

Los puntos planteados sobre la precisión son ciertamente válidos. Un IEEE float tiene solo 24 bits de precisión, que es menos que un entero de 32 bits. El uso de double para cálculos intermedios empujará todas las pérdidas por redondeo y precisión a la conversión de nuevo a float o int.

+0

+1 para el enlace WECSSKAFPA, que me salvó de navegarlo. :) – unwind

+0

Le di una ojeada al papel, podría postergarlo hasta después ...jaja – sevenboarder

+0

Es un poco pesado en matemáticas ... pero puedes pasar todas las pruebas y obtener los puntos importantes. El gran punto importante es que no siempre es simple ... – RBerteig

8

La aritmética de modo mixto (aritmética entre operandos de diferentes tipos y/o tamaños) es legal pero frágil. El estándar C define reglas para la promoción de tipos para convertir los operandos a una representación común. La promoción automática de tipos permite al compilador hacer algo sensato para las operaciones en modo mixto, pero "sensible" no significa necesariamente "correcto".

Para saber realmente si el comportamiento es correcto o no, primero debe comprender las reglas de promoción y luego comprender la representación de los tipos de datos. En términos muy generales:

  • más corto tipos se convierten a tipos más largos (float a double, short a int, etc.)
  • tipos de enteros se convierten a los tipos de punto flotante
  • firmados/unsigned las conversiones favorecen evitar la pérdida de datos (si se firma se convierte a sin firmar o viceversa dependiendo del tamaño de los tipos respectivos)

Si el código como x > y (donde x y y tienen tipos diferentes) es correcto o incorrecto depende de los valores que x y y pueden tomar. En mi experiencia, es una práctica común prohibir (a través del estándar de codificación) las conversiones de tipo implícito. El programador debe considerar el contexto y realizar explícitamente cualquier conversión de tipo necesaria.

0

Acerca de eso, la notación 1.0 es de tipo double, por lo que la comparación se realiza en doble por tipo según las reglas de promoción anteriores. 1.f o 1.0f es de tipo float y la comparación se habría realizado en float. Y hubiera funcionado también, ya que dijimos que 2^23 primeros números enteros son representables en una carroza.

Cuestiones relacionadas