Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

167
Views
¿Cuál es la forma correcta de almacenar el resultado de una expresión flotante en una variable int en C?

Consideremos el siguiente fragmento de código:

 #include <stdio.h> int main() { float dollars; int cents; dollars = 159.95; cents = dollars*100; printf("Dollars:%f\tCents:%d\n",dollars,cents); return 0; }

La salida sería:

 Dollars: 159.949997 Cents:15995

Entiendo que 159.95 no tiene una representación precisa en binario. Pero no estoy seguro de por qué el valor 15995 se almacena en la variable centavos.

Me preguntaba si en estos casos sería conveniente usar round en la expresión, de esta forma:

 cents = round(dollars*100);

¿Cuál es la mejor práctica para tratar esos casos?

Por favor, tenga en cuenta que este ejemplo usando moneda es solo un ejemplo. Me gustaría discutir el caso general. ¿Existe alguna práctica recomendada general para realizar este tipo de operación?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

159.95 no tiene una representación precisa

Eso es correcto (como muestra su llamada printf ). Sin embargo, la operación dollars * 100 , que se realiza con al menos una precisión de float 1 , arroja un valor de exactamente 15595,0000, como demuestra el siguiente código:

 #include <stdio.h> int main() { float dollars = 159.95f; float p = dollars * 100; if (p == 15995.00000) printf("Exact!\n"); else printf("Not exact: truncation may occur!\n"); return 0; }

Que esto suceda aquí es puramente "casual". Si cambia ese 159,95 a (digamos) 159,65, verá el truncamiento esperado en el valor de los cents (15964).

Puede experimentar un poco más, aquí: con un valor de 159,85, por ejemplo, la mejor representación para el valor calculado de dollars * 100 es ligeramente mayor que el valor exacto (15985,000977), por lo que el truncamiento tampoco ocurrirá en ese caso .


1 El 100 , que es un literal int , se convierte en un float antes de realizar la operación de multiplicación.

over 4 years ago · Santiago Trujillo Report

0

¿Cuál es la mejor práctica para tratar esos casos?

Cuando se trata de divisas, lo mejor suele ser * no utilizar flotantes. Use números enteros para esos. Estos son algunos de los problemas con los flotantes cuando se trata de divisas:

  • La mayoría de las fracciones decimales no se pueden representar exactamente

  • Cuando los números se vuelven demasiado grandes, los flotadores pierden precisión silenciosamente en los últimos dígitos enteros

Pero simplemente usar un número entero no es suficiente. Si solo almacena la cantidad de centavos, es probable que tenga problemas al hacer cálculos con intereses y demás. En su lugar, desea almacenar, por ejemplo, miles de centavos. Un milicent si quieres. Pero tenga en cuenta que esto no resuelve automáticamente todos los problemas con él.

También tenga en cuenta que almacenar milicentés requerirá números enteros muy grandes. un número de 32 bits puede almacenar 4 mil millones de milicentés, lo que sería solo 40.000 dólares. Por lo tanto, se prefiere un número entero de 64 bits.

Aquí hay una publicación que describe muy bien los problemas con el uso de flotantes para la moneda: https://software.codidact.com/posts/284175

Una cita de la respuesta de celtschk en el enlace de arriba:

Por ejemplo, digamos que tienes 128 dólares invertidos con un interés del 0,6%, pero en el primer año solo obtienes la mitad de ese porcentaje. Entonces, ¿cuánto obtienes en el primer año? Bueno, obviamente el 0,3% de 128 dólares son 38,4 centavos, que luego se redondean a 38 centavos. Pero hagamos el cálculo de otra manera: primero, calculamos el interés que normalmente obtendrías: el 0,6% de 128 dólares son 76,8 centavos, que se redondean a 77 centavos. Y luego la mitad de esto son 38,5 centavos que se redondean a 39 centavos. Este es un centavo más.

Para evitar este tipo de error, los cálculos intermedios siempre deben hacerse con una mayor precisión, y solo el resultado final debe convertirse a centavos enteros con el redondeo adecuado.

* Sin embargo, ninguna regla está exenta de excepciones. Citado de esta respuesta :

Para dar un ejemplo, una vez participé en una larga discusión con un programador que insistía en representar los flujos de caja con decimales en lugar de números de punto flotante en un software de computación de riesgos. En las aplicaciones de contabilidad, los decimales son, por supuesto, la única opción sensata (o los números enteros), pero para la gestión de riesgos que utiliza muchos modelos estocásticos y aproximaciones numéricas, los números de coma flotante son la opción correcta.

Como Eric Postpischil mencionó en los comentarios a continuación:

La "solución" es comprender las matemáticas y los tipos de representaciones que se utilizan y diseñar software para las situaciones particulares.

Si no estamos hablando de moneda, sino del caso general de "convertir flotante a int", entonces no hay realmente ninguna mejor práctica. Todo se reduce a la situación individual. El uso round normalmente dará resultados "más correctos".

over 4 years ago · Santiago Trujillo Report

0

dollar*100 es una variable flotante. Sucede que el resultado de la multiplicación es exactamente un número entero (que no está garantizado en absoluto debido a la imprecisión del punto flotante).

Entonces, cuando asignas dollar*100 a un número entero, la parte fraccionaria se pierde, pero en este caso particular no tiene impacto ya que no hay parte fraccionaria. Entonces, por casualidad, la variable cents es más precisa que dollars .

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!