Foros aprenderaprogramar.com

Aprender a programar => C, C++, C#, Java, Visual Basic, HTML, PHP, CSS, Javascript, Ajax, Joomla, MySql y más => Mensaje iniciado por: Pino06-01-2016 en 09 de Enero 2016, 14:48

Título: Contar cantidad de dígitos a la derecha de la coma [lenguajeC] hallar decimales
Publicado por: Pino06-01-2016 en 09 de Enero 2016, 14:48
Hola. El programa que muestro a continuación lo que hace es separar los dígitos que se encuentran a la izquierda de la coma y los que se encuentran a la derecha, o sea, la parte entera y la parte fraccionaria de una variable double, hasta hay todo bien, el error lo tengo cuando el bucle for no coincide con la cantidad de dígitos fraccionarios.-
Alguien me puede decir si es posible establecer cuantos dígitos ha ingresado el operador a la derecha de la coma, he intentado por todos los medios a mi alcance (lectura y búsqueda en la web) y no pude lograrlo.-

Código: [Seleccionar]
#include <stdio.h>
#include <float.h>

int main( void ){
double numero , decimal;
int entero, x = 1, ok, ch;

do{
printf("\n Ingrese un numero con decimales...: ");
ok = scanf( "%lf", &numero ) == 1 && numero > 0.00 && numero <= DBL_MAX;
while ((ch = getchar()) != EOF && ch != '\n');
}while(!ok);
 
entero = (int)numero;
decimal = numero - entero;

while(x <= 4 ){
decimal  *=10;
x++;
}
 
printf("\n La parte fraccionaria..:%g\n", decimal);
 
return 0;
}

Gracias y saludos.
Título: Re:Establecer cantidad de dígitos a la derecha de la coma [lenguajeC] decimales
Publicado por: Ogramar en 11 de Enero 2016, 14:17
Hola Pino no sé si esta idea te puede servir (tomada de http://aprenderaprogramar.com/index.php?option=com_content&view=article&id=941:ejercicios-codificacion-c-dibujar-rombo-diamante-arreglos-unidimensionales-calcular-sumatorios-cu00542f&catid=82:curso-basico-programacion-lenguaje-c-desde-cero&Itemid=210)

Para limitar el número de decimales utilizado se puede introducir un número junto al indicador de tipo de dato

Por ejemplo scanf( "%.2lf", &numero ) haría que se tomaran dos valores decimales

Se ha introducido .n (por ejemplo .2) después del símbolo % para indicar que se tomen n decimales

Otro ejemplo sería:

printf ("El precio del libro con isbn %.0lf es de %.2lf euros ", isbn, precio);

El primer número no mostraría decimales y el segundo mostraría dos decimales

Salu2
Título: Re:Establecer cantidad de dígitos a la derecha de la coma [lenguajeC] decimales
Publicado por: Pino06-01-2016 en 12 de Enero 2016, 13:06
Hola.
Gracias por ocuparte, el caso es un tanto sencillo, te pongo un ejemplo, se ingresa por teclado 123.456 para extraer la parte entera y la parte decimal utilizo estas 2 lineas de código:

Código: [Seleccionar]
entero = (int)numero;
decimal = numero - entero;

El resultado de la parte fraccionaria (que es la que no puedo resolver) es 0.456, para llegar a obtener tan solo 456 o sea sin parte fraccionaria como si fuera un entero debo saber de antemano por cuanto tengo que multiplicarlo en este caso x 1.000.-

12.3 la parte fraccionaria multiplicada x 10 es igual a 3   
12.34 la parte fraccionaria multiplicada x 100 es igual a 34   
12.345 la parte fraccionaria multiplicada x 1000 es igual a 345

Te voy a ser muy franco, ya estoy por tirar la toalla, hace una semana que estoy con el tema y parece que no tiene manera de lograrse.-

Ojalá Dios te ilumine y puedas ayudarme.-

Nota: recordar que no puedo utilizar el tipo char.- 

Saludos.
Título: Re:Establecer cantidad de dígitos a la derecha de la coma [lenguajeC] decimales
Publicado por: Ogramar en 12 de Enero 2016, 14:13
Buenas, pues parece un problema sencillo pero no lo es, en parte por la forma de representación interna numérica que usan los computadores ya que lo que vemos en pantalla no es lo que usa el computador internamente.

La idea que podrías usar es partir de lo que tú has indicado como vía para obtener la parte fraccionaria, y luego irla reduciendo hasta que puedas determinar que has contabilizado todos los dígitos decimales. Es decir, tomar la parte entera haciendo un redondeo y luego multiplicar por 10, así hasta que llegues a cero:

Por ejemplo partimos de un número cuya parte decimal sea .2155 y multiplicamos por 10

.2155 * 10 = 2.155 le restamos la parte entera y nos queda .155 (contador: un decimal)
.155 * 10 = 1.55 le restamos la parte entera y nos queda .55 (contador: dos decimales)
.55 * 10 = 5.5 le restamos la parte entera y nos queda .5 (contador: tres decimales)
.5 * 10 = 5.0 le restamos la parte entera y nos queda cero (contador: cuatro decimales)

4 multiplicaciones por diez hasta llegar a cero, serían 4 decimales

Expresado ya con la idea de código sería algo como esto:

Código: [Seleccionar]
count = 0
num = abs(num)
num = num - int(num)
while num != 0:
    num = num * 10
    count = count + 1
    num = num - int(num)

No lo he probado pero parece que podría funcionar tanto para contar el número de decimales como para saber cuáles son esos decimales

Salu2
Título: Re:Establecer cantidad de dígitos a la derecha de la coma [lenguajeC] decimales
Publicado por: Pino06-01-2016 en 12 de Enero 2016, 19:24
Hola, Ogramar.
Créeme que ya me canse de practicar y no doy con el error, te dejo el código por si quieres revisarlo y una captura ingresando el número que propusiste.- 

(http://i65.tinypic.com/n62ww6.png)

Código: [Seleccionar]
#include <stdio.h>
#include <float.h>
#include <stdlib.h>

int main( void ){
double numero , decimal;
int entero, contador = 0, ok, ch;

do{
printf("\n Ingrese un numero con decimales...: ");
ok = scanf( "%lf", &numero ) == 1 && numero > 0.00 && numero <= DBL_MAX;
while ((ch = getchar()) != EOF && ch != '\n');
}while(!ok);
 
entero = (int)numero;
decimal = numero - entero;

while(decimal != 0 ){
decimal = decimal * 10;
decimal = decimal - (int)decimal;
printf("\n Decimal...: %g", decimal);
// getchar();
contador ++;
}
 
printf("\n Total de digitos despues de la coma..:%d\n", contador);
 
return 0;
}

Saludos.
Título: Re:Establecer cantidad de dígitos a la derecha de la coma [lenguajeC] decimales
Publicado por: Ogramar en 14 de Enero 2016, 21:14
Buenas Pino, he hecho pruebas y pienso que el problema está en la precisión decimal y en la forma interna (con base 2) de manejo de números por parte del lenguaje.

Si introduzco 5.25 obtengo esto:


 Ingrese un numero con decimales...: 5.25
El entero es 5
El decimal es 0.250000
Por 10 hemos obtenido 2.500000
La parte entera es 2

 Tras restar parte entera hemos obtenido Decimal...: 0.500000
Por 10 hemos obtenido 5.000000
La parte entera es 5

 Tras restar parte entera hemos obtenido Decimal...: 0.000000
 Total de digitos despues de la coma..:2

Si introduzco 5.22 obtengo esto:


 Ingrese un numero con decimales...: 5.22
El entero es 5
El decimal es 0.220000
Por 10 hemos obtenido 2.200000
La parte entera es 2
Tras restar parte entera hemos obtenido Decimal...: 0.200000
Por 10 hemos obtenido 2.000000
La parte entera es 1

Aquí ya vemos cómo ha fallado. Nos está diciendo que la parte entera de 2 es 1 ¿Por qué? Porque la representación interna que utiliza el computador quizá le lleve a tomar otro valor en lugar de 2, y nos dice que la parte entera es 1.

Supongo que dándole vueltas se podrá resolver, pero no es sencillo...

Salu2
Título: Re:Establecer cantidad de dígitos a la derecha de la coma [lenguajeC] decimales
Publicado por: Pino06-01-2016 en 15 de Enero 2016, 15:46
Hola, Ogramar.
Muchas gracias por todo lo que hiciste para que funcione, no te ocupes más de este asunto, tal vez cuando lo olvides, te caiga la ficha, yo voy a seguir intentando, no me cabe que la fórmula que propusiste no funcione. -

Un fuerte abrazo.
Título: Re:Contar cantidad de dígitos a la derecha de la coma [lenguajeC] hallar decimales
Publicado por: Ogramar en 17 de Enero 2016, 20:11
Buenas Pino, he vuelto a mirarlo pero no encuentro demasiada inspiración; sigo encontrando el problema de la representación interna del número que usa el computador.

El asunto deriva de la representación binaria de números decimales. Algunos números tienen una representació exacta, pero otros son solo aproximaciones. Si almacenamos por ejemplo 3.44 en un double, el valor real almacenado en el sistema puede ser 3.439999999999999946709294817992486059665679931640625, que tiene 51 posiciones dígitos en su parte decimal (aunque nosotros por pantalla veamos 3.44). Para C 3.44 y 3.439999999999999946709294817992486059665679931640625 vienen siendo el mismo número, de ahí la dificultad de poder decir cuántos decimales tiene. Si el número que internamente guarda el computador es 3.439999999999999946709294817992486059665679931640625 ¿Por qué íbamos a ser capaces de decir que tiene 2 decimales? (Realmente en la representación interna no los tiene).

Podría tratar de detectarse a qué valor está próximo el número, pero eso también es complejo sobre todo porque no estaría claro a qué número se debe aproximar un número con 51 dígitos decimales.

Una aproximación a resolver el problema sería basarse en convertirlo a string, extraer los tokens, hacer el conteo y devolver el número de decimales

Código: [Seleccionar]
#include <stdio.h>
#include <string.h>

/* Counting the number of decimals
 *
 * 1. Use Scientific Notation format
 * 2. Convert it to a string
 * 3. Tokenize it on the exp sign, discard the base part
 * 4. convert the second token back to number
*/

int main(){

   int counts;
   char *sign;
   char str[15];
   char *base;
   char *exp10;
   float real = 0.00001;

   sprintf (str, "%E",  real);
   sign= ( strpbrk ( str, "+"))? "+" : "-";

   base = strtok (str, sign);
   exp10 = strtok (NULL, sign);

   counts=atoi(exp10);

   printf("[%d]\n", counts);

   return 0;
}


Salu2