romanos numeros naturales mostrar los limitar float decimales convertir como c++ c decimal

numeros - float c++



¿C/C++ contando el número de decimales? (11)

¿Qué quiere decir "almacenado libremente (int")? Una vez almacenado en un int, tiene cero decimales, claramente. Un doble se almacena en forma binaria, por lo que tampoco existe una relación obvia o simple con "decimales". ¿Mantiene la entrada como una cadena, lo suficiente para contar esos decimales, antes de enviarla a su destino final de variable numérica?

Digamos que la entrada del usuario es un número decimal, ej. 5. 2155 (teniendo 4 dígitos decimales). Se puede almacenar libremente (int, doble) etc.

¿Hay alguna forma inteligente (o muy simple) de averiguar cuántos decimales tiene el número? (un poco como la pregunta, ¿cómo encuentra que un número es par o impar al enmascarar el último bit)?


Años después de la pelea pero como he hecho mi propia solución en tres líneas:

string number = "543.014"; size_t dotFound; stoi(number, &dotFound)); string(number).substr(dotFound).size()

Por supuesto, tiene que probar antes si es realmente un flotador (con stof(number) == stoi(number) por ejemplo)


Algo como esto podría funcionar también:

float i = 5.2154; std::string s; std::string t; std::stringstream out; out << i; s = out.str(); t = s.substr(s.find(".")+1); cout<<"number of decimal places: " << t.length();


Aquí está el programa completo

#include <iostream.h> #include <conio.h> #include <string.h> #include <math.h> char charary[10]={''1'',''2'',''3'',''4'',''5'',''6'',''7'',''8'',''9'',''0''}; int intary[10]={1,2,3,4,5,6,7,8,9,0}; char* intpart(double); char* fractpart(double); int main() { clrscr(); int count = 0; double d = 0; char intstr[10], fractstr[10]; cout<<"Enter a number"; cin>>d; strcpy(intstr,intpart(d)); strcpy(fractstr,fractpart(d)); cout<<intstr<<''.''<<fractstr; getche(); return(0); } char* intpart(double f) { char retstr[10]; int x,y,z,count1=0; x=(int)f; while(x>=1) { z=x%10; for(y=0;y<10;y++) { if(z==intary[y]) { chrstr[count1]=charary[y]; break; } } x=x/10; count1++; } for(x=0,y=strlen(chrstr)-1;y>=0;y--,x++) retstr[x]=chrstr[y]; retstr[x]=''/0''; return(retstr); } char* fractpart(double f) { int count=0,x,y; f=f-(int)f; while(f<=1) { f=f*10; for(y=0;y<10;y++) { if((int)f==intary[y]) { chrstr[count]=charary[y]; break; } } f=f-(int)f; if(f<=0.01 || count==4) break; if(f<0) f=-f; count++; } return(chrstr); }


De dos formas que conozco, ninguna muy inteligente por desgracia, pero esto es más una limitación del entorno que de mí :-)

La primera es sprintf el número a un búfer grande con una cadena de formato "%.50f" , eliminar los ceros finales y luego contar los caracteres después del punto decimal. Esto estará limitado por la propia familia printf . O puede usar la cadena como entrada del usuario (en lugar de sprintf un valor de punto flotante), para evitar por completo los problemas de punto flotante.

El segundo es restar la parte entera, luego multiplicar iterativamente por 10 y nuevamente restar la parte entera hasta obtener cero. Esto está limitado por los límites de la representación por computadora de los números de punto flotante: en cada etapa puede obtener el problema de un número que no se puede representar exactamente (por lo tanto, .2155 puede ser .215499999998). Algo como lo siguiente (sin probar, excepto en mi cabeza, que está a la par con un COMX-35):

count = 0 num = abs(num) num = num - int(num) while num != 0: num = num * 10 count = count + 1 num = num - int(num)

Si sabe el tipo de números que obtendrá (por ejemplo, todos serán de 0 a 4 dígitos después del punto decimal), puede usar "trucos" de punto flotante estándar para hacerlo correctamente. Por ejemplo, en lugar de:

while num != 0:

utilizar

while abs(num) >= 0.0000001:


La parte superior de mi cabeza:

comenzar con la porción fraccionaria: .2155

multiplica repetidamente por 10 y tira la parte entera del número hasta que obtengas cero. El número de pasos será el número de decimales. p.ej:

.2155 * 10 = 2.155 .155 * 10 = 1.55 .55 * 10 = 5.5 .5 * 10 = 5.0

4 pasos = 4 dígitos decimales


Una forma sería leer el número como una cadena. Encuentra la longitud de la subcadena después del punto decimal y esa es la cantidad de decimales que ingresó la persona. Para convertir esta cadena en un flotador utilizando

atof(string.c_str());

En una nota diferente; Cuando se trata de operaciones de punto flotante, siempre es una buena idea almacenarlas en un objeto especial que tenga una precisión finita. Por ejemplo, podría almacenar los puntos flotantes en un tipo especial de objeto llamado "Decimal" donde la parte del número entero y la parte decimal del número son ambas entradas. De esta manera tienes una precisión finita. La desventaja de esto es que tiene que escribir métodos para operaciones aritméticas (+, -, *, /, etc.), pero puede sobrescribir fácilmente los operadores en C ++. Sé que esto se desvía de tu pregunta original, pero siempre es mejor almacenar tus decimales en forma finita. De esta manera también puede responder a su pregunta de cuántos decimales tiene el número.


Una vez que el número se convierte de la representación del usuario (cadena, archivo gif OCR-ed, lo que sea) a un número de punto flotante, no se trata necesariamente del mismo número. Así que la respuesta estricta, no muy útil es "No".

Si ( caso A ) puede evitar convertir el número de la representación de cadena, el problema se vuelve mucho más fácil, solo necesita contar los dígitos después del punto decimal y restar el número de ceros finales.

Si no puede hacerlo ( caso B ), debe hacer una suposición sobre el número máximo de decimales, volver a convertir el número en representación de cadena y redondearlo a este número máximo utilizando el método de redondeo a par . Por ejemplo, si el usuario proporciona 1.1 que se representa como 1.09999999999999 (hipotéticamente), convirtiéndolo nuevamente en rendimientos de cadena, adivine qué, "1.09999999999999". Redondear este número a, digamos, cuatro puntos decimales le da "1.1000". Ahora es el caso A.


Yo sugeriría leer el valor como una cadena, buscar el punto decimal y analizar el texto antes y después como números enteros. No hay errores de punto flotante o redondeo.


usando el formato de Notación Científica (para evitar errores de redondeo):

#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; }

[5]


char* fractpart(double f) { int intary={1,2,3,4,5,6,7,8,9,0}; char charary={''1'',''2'',''3'',''4'',''5'',''6'',''7'',''8'',''9'',''0''}; int count=0,x,y; f=f-(int)f; while(f<=1) { f=f*10; for(y=0;y<10;y++) { if((int)f==intary[y]) { chrstr[count]=charary[y]; break; } } f=f-(int)f; if(f<=0.01 || count==4) break; if(f<0) f=-f; count++; } return(chrstr); }