2012-10-09 76 views
5

que necesitaba para convertir una parte fraccionaria de un número en un entero sin una coma, por ejemplo tengo 3,35 quiero obtener sólo 35 parte sin cero o una coma,C++ convertir una parte fraccionaria de un número en número entero

Porque utilicé la función modf() para extraer la parte fraccionaria pero me da 0,35 si hay alguna manera de hacerlo o para filtrar el '0'. Estoy muy agradecido si me muestra cómo con el código más pequeño posible,

+8

¿Siempre hay solo dos decimales? ¿Qué tal multiplicar por 100 y convertir a un número entero? –

+2

formatéelo en una cadena, luego copie todo después del decimal, o elimine todo hasta el primer carácter numérico. (luego puede convertir eso a un int, si eso es lo que necesita) – Mordachai

+0

La representación binaria de 3.35 es probablemente '3.349999986f' más o menos. La representación binaria de 3.350 es la misma. ¿Qué espera exactamente como resultado, dadas las dos entradas 3.35 y 3.350? – MSalters

Respuesta

-1

Así es como lo haría.

#include <sstream> 
#include <string> 

int main() 
{ 
    double d = yourDesiredNumber; //this is your number 
    std::ostringstream out; 
    out << setprecision(yourDesiredPrecision) << std::fixed 
     << std::showpoint << d; 
    std::istringstream in(out.str()); 
    std::string wholePart; //you won't need this. 
    int fractionalPart; 
    std::getline(in, wholePart, '.'); 
    in >> fractionalPart; 
    //now fractionalPart contains your desired value. 
} 

Estoy bastante seguro de que en lugar de dos diferentes istringstream y ostringstream objetos que podrían haber salido con un solo stringstream objeto, pero no estoy seguro acerca de los detalles (nunca usado esa clase), de manera Yo no t usarlo en el ejemplo.

+2

No haría esto. Es lento y con pérdidas ... –

+1

@ RichardJ.RossIII: Honestamente estoy esperando que publiques una respuesta para ver qué * tu * harías. –

+0

Esto me recuerda la siguiente cita: http://bash.org/?946461 –

0

otra solución

int precision= 100; 
double number = 3.35; 
int f = floor(xx); 
double temp = (f - number) * -1; 
int fractional_part = temp * precision; 
+1

¿Qué tal 'number - f' en lugar de' (f - number) * -1'? –

+2

Esto no funciona correctamente para números negativos. -0.1 da 90 – digitalvision

0

si lo necesita como una cadena, sería una solución muy fácil de estilo C (debería funcionar para el número variable de decimales):

double yourNumber = 0.35f; 
    char buffer[32]; 
    snprintf(buffer, 32, "%g", yourNumber); 
    strtok(buffer, "."); // Here we would get the part before . , should still check 
    char* fraction = strtok(NULL, "."); 
    int fractionAsInt = atoi(fraction); 

Este ejemplo le falta manejo de errores en caso de una cadena incorrecta y no es factible si solo necesita un número fijo de decimales, ya que los enfoques aritméticos funcionan mejor allí.

3

un poco más eficiente que la conversión de una cadena y vuelta a empezar:

int fractional_part_as_int(double number, int number_of_decimal_places) { 
    double dummy; 
    double frac = modf(number,&dummy); 
    return round(frac*pow(10,number_of_decimal_places)); 
} 
0

Algo como esto debería funcionar:

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

static int get_frac(double value, unsigned short precision) 
{ 
    return (int)((value - (long)value) * pow(10, precision)); 
} 

static int get_frac_no_trailing_zeros(double value, unsigned short precision) 
{ 
    int v = get_frac(value, precision); 
    while (v % 10 == 0) 
     v /= 10; 
    return v; 
} 

int main(int argc, char *argv[]) 
{ 
    double v; 

    v = 123.4564; 
    printf("%.4f = %d\n", v, get_frac(v, 2)); 
    printf("%.4f = %d\n", v, get_frac(v, 4)); 
    printf("%.4f = %d\n", v, get_frac(v, 6)); 
    printf("%.4f = %d\n", v, get_frac_no_trailing_zeros(v, 6)); 

    return EXIT_SUCCESS; 
} 

También es posible que desee evitar o bien llamando pow por tener un usuario suministre un número con una potencia de 10 en primer lugar, o use una tabla de búsqueda.

0

Usando un poco de magia STL, here is el código de ejemplo:

typedef std::pair<int, int> SplitFloat; 

SplitFloat Split(float value, int precision) 
{ 
    // Get integer part. 
    float left = std::floor(value); 
    // Get decimal part. 
    float right = (value - left) * float(std::pow(10, precision)); 

    return SplitFloat(left, right); 
} 

Se puede mejorar, pero es bastante sencillo.

1
#include <iostream> 
#include <cmath> 

double round(double r) { 
    return (r > 0.0) ? std::floor(r + 0.5) : std::ceil(r - 0.5); 
} 

double floor_to_zero(double f) { 
    return (f > 0.0) ? std::floor(f) : std::ceil(f); 
} 

double sign(double s) { 
    return (s < 0.0) ? -1.0 : 1.0; 
} 

int frac(double f, int prec) { 
    return round((f - floor_to_zero(f)) * prec) * sign(f); 
} 

int main() { 
    double a = 1.2345; 
    double b = -34.567; 
    std::cout << frac(a, 100) << " " << frac(b, 100) << std::endl; // 23 57 
} 
0

Acabo de hacer algo parecido a lo que intentan hacer, aunque sigo siendo bastante nuevo. Sin embargo, tal vez esto ayude a alguien en el futuro cuando llegue aquí buscando resultados para mi problema.

El primer paso es asegurarse de que la variable que contiene 3.35 es doble, pero eso es probablemente obvio.

A continuación, cree una variable que sea solo un número entero y establezca su valor igual al valor del doble. Entonces solo contendrá el número entero.

Luego resta el número entero (int) del doble. Te quedarás con el valor de fracción/decimal. A partir de ahí, simplemente multiplique por 100.

Más allá del valor decimal de centésimas, tendría que hacer un poco más de configuración, obviamente, pero debería ser bastante simple de hacer con una instrucción if. Si el valor decimal es mayor que .99, multiplica 1000 en cambio, etc.

Cuestiones relacionadas