2010-11-10 11 views
5

básicamente quiero devolver el número de dígitos en el int -> valores de la siguiente manera:encontrar la "longitud de cadena" de un int

(int)1 => 1 
(int)123 => 3 
(int)12345678 => 8 

No sé nada de C, así que por favor tengan paciencia conmigo. Conozco el objetivo c, pero utilizo ints y floats en lugar de NSNumbers. Me doy cuenta de que podría convertir los enteros en objetos objetivos c, pero esto parece una mentira, y si puedo hacerlo con C lo sabré para el futuro.

Gracias

Respuesta

22

uso

int d = (value == 0 ? 1 : (int)(log10(value)+1)); 

Tenga en cuenta que este no funciona para los números negativos, se tendrá que utilizar

int d = (value == 0 ? 1 : ((int)(log10(fabs(value))+1) + (value < 0 ? 1 : 0))); 

que una dds 1 para el signo menos, si value es negativo.

+0

gracias martin. +1 por darme 0 y menos números. :) –

+0

+1 para el mismo – DVK

+2

(valor <0? 1: 0) es equivalente a just (valor <0) – Vovanium

5

Use logaritmos en base 10:

int length = (int)floor(log10((float)number)) + 1; // works for >0 
+0

muchas gracias. :) –

1

Una solución más general, sobre todo si quieres saber la longitud para los propósitos de la impresión con printf() variantes es:

snprintf(NULL, 0, "%d", myint); 

El valor de retorno que debe contar la longitud de la cadena que se imprime.

+0

@pst: ¿Por qué cortaste la parte '\ 0'? – aib

+0

El NUL no está incluido en la longitud de la cuerda simplemente por ser una cadena en C. (Fue solo el fraseo utilizado.) –

10

Probablemente mucho más rápido que el uso de registro o conversión int-a-cuerda y sin el uso de funciones de la biblioteca es la siguiente:

int nDigits(int i) 
{ 
    if (i < 0) i = -i; 
    if (i <   10) return 1; 
    if (i <  100) return 2; 
    if (i <  1000) return 3; 
    if (i <  10000) return 4; 
    if (i <  100000) return 5; 
    if (i < 1000000) return 6;  
    if (i < 10000000) return 7; 
    if (i < 100000000) return 8; 
    if (i < 1000000000) return 9; 
    return 10; 
} 

EDITAR después de que Jeff Yates preocupaciones:

Para aquellos que se preocupan por int tamaños diferentes de 32 bits (similar a la solución de pmg pero aún más rápido porque la multiplicación es más rápida que la división :-)

#include <limits.h> 

#define PO10_LIMIT (INT_MAX/10) 


int nDigits(int i) 
{ 
    int n,po10; 

    if (i < 0) i = -i; 
    n=1; 
    po10=10; 
    while(i>=po10) 
    { 
    n++; 
    if (po10 > PO10_LIMIT) break; 
    po10*=10; 
    } 
    return n; 
} 
+1

+1 para el algoritmo más rápido – pmg

+0

Esto solo es bueno si 'int' es un valor de 32 bits. Como el tamaño de 'int' depende de la plataforma en C y C++, no confiaría en esto. –

+0

@Jeff Yates: ¡Lo sé! Si esto, sin embargo, es realmente un problema simplemente agregue/elimine algunas instrucciones si. Y si realmente necesita una solución que funcione en diferentes plataformas, puede trabajar con # si prueba el tamaño del tipo de int en particular o usar la solución de pmg (que aún se puede optimizar). – Curd

4

Aquí hay otra opción

int nDigits(unsigned i) { 
    int n = 1; 
    while (i > 9) { 
     n++; 
     i /= 10; 
    } 
    return n; 
} 

Esto es más rápido que usar log10, pero más lento que la opción de la cuajada con las pruebas en cascada. Sin embargo, no asume int s son de 32 bits :-)

1

Si su valor entero (por ejemplo 12345678u) es una constante en tiempo de compilación, puede dejar que el compilador determinar la longitud para usted:

template<typename T> 
constexpr unsigned int_decimal_digits(T value) 
{ 
    return ( value/10 
        ? int_decimal_digits<T>(value/10) + 1 
        : 1); 
} 

Uso:

unsigned n = int_decimal_digits(1234); 
// n = 4 

#include <limits.h> 
unsigned m = int_decimal_digits(ULLONG_MAX); 
// m = maximum length of a "long long unsigned" on your platform 

de esta manera, el compilador calcular el número de decimales de forma automática, y rellenar el valor como una constante. Debería ser la solución más rápida posible, porque no hay cálculos de tiempo de ejecución implicados y las constantes enteras generalmente se incluyen en los códigos de operación de la instrucción. (Esto significa que viajan por canalización de instrucciones, no por memoria de datos/caché). Sin embargo, esto requiere un compilador que admita C++ 11.

Cuestiones relacionadas