¿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?
¿Cómo extraer la parte decimal de un número de punto flotante en C?
Binu
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 imprimirdouble
. 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 flotantedecpart
no puede representar0.1
.– 0b101010
28/04/2015 a las 15:50
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
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
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
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
}
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
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