¿Cómo extraer la parte decimal de un número de punto flotante en C?

6 minutos de lectura

avatar de usuario
Binu

¿Cómo podemos extraer la parte decimal de un número de punto flotante y almacenar la parte decimal y la parte entera en dos variables enteras separadas?

  • No veo cómo podrías poner la parte decimal en un número entero a menos que supieras cuántos dígitos quieres conservar. ¿Podría dar algunos ejemplos?

    – Nosredna

    1 de febrero de 2009 a las 1:16

  • quiero obtener la parte decimal como un número entero para cualquier valor de entrada. por lo que el número de dígitos en la parte decimal no se puede predecir.

    – Binú

    1 de febrero de 2009 a las 1:25

  • como si ingresas 16.25 quiero obtener 25 en un valor entero también si el número es 0.3215769 quiero obtener 3215769 en un número entero como ese

    – Binú

    1 de febrero de 2009 a las 1:33

  • leyendo una cadena, luego verificando si la cadena es un doble (existen preguntas en SO que se responden diciendo cómo hacerlo), y luego obteniendo las cosas después de “.”. ¿Qué hay de eso? ¿O también necesita leer otros formatos (10e-5)?

    – Johannes Schaub – litb

    1 de febrero de 2009 a las 1:49

  • ¿Cómo distinguirías las fracciones decimales en 1.5 y 1.005?

    – Eliminación de negación simple

    5 de junio de 2009 a las 12:16

avatar de usuario
Johannes Schaub – litb

usas el modf función:

double integral;
double fractional = modf(some_double, &integral);

También puede convertirlo en un número entero, pero tenga en cuenta que puede desbordar el número entero. El resultado no es predecible entonces.

  • @penu Es porque estás usando %d para imprimir double. Aquí está el código de trabajo: codepad.org/kPGKtcZi

    – Sam Protsenko

    20 de marzo de 2016 a las 19:47

  • Este código trunca 123.456745693850 de 0.45674569385 a 0.456746

    usuario5125586

    24 de febrero de 2021 a las 9:13

  • @Richard puede abrir una nueva pregunta de stackoverflow para preguntar por qué haría eso en su máquina. No tengo ni idea.

    – Johannes Schaub – litb

    25 de febrero de 2021 a las 21:30


Prueba esto:

int main() {
  double num = 23.345;
  int intpart = (int)num;
  double decpart = num - intpart;
  printf("Num = %f, intpart = %d, decpart = %f\n", num, intpart, decpart);
}

Para mí, produce:

Num = 23.345000, intpart = 23, decpart = 0.345000

Que parece ser lo que estás pidiendo.

  • la primera parte es correcta pero desea obtener el resultado como parte decimal como 345000 entero

    – Binú

    1 de febrero de 2009 a las 1:03

  • pero quiero obtener la parte decimal como valor entero, lo que significa decpart=345000

    – Binú

    14 de marzo de 2009 a las 16:11

  • int decpart = 100000*(num – intpart);

    – Eliminación de negación simple

    5 de junio de 2009 a las 12:14

  • Este método es susceptible a algunos problemas desagradables de coma flotante. Intenta configurar num = 1.1 para un ejemplo rápido. Como un número de punto flotante decpart no puede representar 0.1.

    – 0b101010

    28/04/2015 a las 15:50

avatar de usuario
Trevor Boyd Smith

La respuesta rápida “en pocas palabras” más obvia parece:

#define N_DECIMAL_POINTS_PRECISION (1000) // n = 3. Three decimal points.

float f = 123.456;
int integerPart = (int)f;
int decimalPart = ((int)(f*N_DECIMAL_POINTS_PRECISION)%N_DECIMAL_POINTS_PRECISION);

Cambiaría la cantidad de puntos decimales que desea cambiando el N_DECIMAL_POINTS_PRECISION para satisfacer sus necesidades.

  • Solo por diversión. Hagamos un experimento mental: la solución más ofuscada y compleja (ver “código difícil de mantener”) podría llegar tan lejos como [bit slicing][1] el flotador o el doble para obtener el real [“integerBits” and “fractionalBits”][2].

    – Trevor Boyd Smith

    26 de marzo de 2009 a las 3:53

  • No estoy exactamente seguro de por qué haría esto… tal vez este método tendría la ventaja de capturar las partes enteras y decimales directamente sin perder nada de la precisión debido al redondeo de punto flotante.

    – Trevor Boyd Smith

    26 de marzo de 2009 a las 3:54

  • Aquí hay un pseudocódigo incompleto para darle una idea: #define BIT_MASK1 /* no estoy seguro / #define SHIFT / no estoy seguro / #definir BIT_MASK2 / no estoy seguro */ float f = 123.456; uint32_t * tmp = (uint32_t *)&f; int parteEntero = (int)f;

    – Trevor Boyd Smith

    26 de marzo de 2009 a las 3:55

  • int decimalPart = (((*tmp)&BIT_MASK1)>>SHIFT)&BIT_MASK2; [1]: en.wikipedia.org/wiki/Bit_mask [2]: en.wikipedia.org/wiki/Q_(number_format)

    – Trevor Boyd Smith

    26 de marzo de 2009 a las 3:56

avatar de usuario
mrwes

Creé una subrutina usando un doble flotante, devuelve 2 valores enteros.


void double2Ints(double f, int p, int *i, int *d)
{ 
  // f = float, p=decimal precision, i=integer, d=decimal
  int   li; 
  int   prec=1;

  for(int x=p;x>0;x--) 
  {
    prec*=10;
  };  // same as power(10,p)

  li = (int) f;              // get integer part
  *d = (int) ((f-li)*prec);  // get decimal part
  *i = li;
}

void test()
{ 
  double df = 3.14159265;
  int   i,d;
  for(int p=2;p<9;p++)
  {
    double2Ints(df, p, &i,&d); printf("d2i (%d) %f = %d.%d\r\n",p, df,i,d);
  }
}

Creo que usar una cadena es la forma correcta de hacerlo en este caso, ya que no sabes a priori la cantidad de dígitos en la parte decimal. Pero no funcionará para todos los casos (p. ej., 1.005), como se mencionó anteriormente en @SingleNegationElimination. Aquí está mi opinión sobre esto:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    char s_value[60], s_integral[60], s_fractional[60];
    int i, found = 0, count = 1, integral, fractional;

    scanf("%s", s_value);

    for (i = 0; s_value[i] != '\0'; i++)
    {
        if (!found)
        {
            if (s_value[i] == '.')
            {
                found = 1;
                s_integral[i] = '\0';
                continue;
            }
            s_integral[i] = s_value[i];
            count++;
        }
        else
            s_fractional[i - count] = s_value[i];
    }
    s_fractional[i - count] = '\0';

    integral = atoi(s_integral);
    fractional = atoi(s_fractional);
    printf("value = %s, integral = %d, fractional = %d\n",
        s_value, integral, fractional);

    return 0;
}

  • Resolviste el problema de una manera que nadie debería intentar resolverlo.

    – bolas ascendentes

    24 de enero de 2020 a las 1:04

avatar de usuario
0xAA55

Usa el número flotante para restar el pisoed valor para obtener su parte fraccionaria:

double fractional = some_double - floor(some_double);

Esto evita el encasillamiento a un número entero, lo que puede causar Desbordamiento si el número flotante es muy grande, un valor entero ni siquiera podría contenerlo.

También por valores negativoseste código te da la parte fraccionaria positiva del número flotante desde piso() calcula el valor entero más grande no mayor que el valor de entrada.

  • Resolviste el problema de una manera que nadie debería intentar resolverlo.

    – bolas ascendentes

    24 de enero de 2020 a las 1:04

avatar de usuario
duquevin

Aquí hay otra manera:

#include <stdlib.h>
int main()
{
    char* inStr = "123.4567";         //the number we want to convert
    char* endptr;                     //unused char ptr for strtod

    char* loc = strchr(inStr, '.');
    long mantissa = strtod(loc+1, endptr);
    long whole = strtod(inStr, endptr);

    printf("whole: %d \n", whole);     //whole number portion
    printf("mantissa: %d", mantissa);  //decimal portion

}

http://codepad.org/jyHoBALU

Producción:

whole: 123 
mantissa: 4567

  • Su código no funcionará en plataformas de 16 bits donde los largos son de 32 bits y los dobles largos son de 53 bits.

    – usuario2284570

    3 mayo 2015 a las 15:37

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad