2010-07-16 33 views
18

estoy leyendo un programa que contiene la siguiente función, que es¿Qué hace esta función?

int f(int n) { 
    int c; 
    for (c=0;n!=0;++c) 
     n=n&(n-1); 
    return c; 
} 

yo no entiendo muy bien lo que tiene intención de esta función para hacer?

+44

Lo que demuestra que 'f' es un nombre terrible para esta función. –

+1

Un comentario o dos no habría dolido, tampoco. –

+3

El código se ve mal, pero después de 30 segundos parece bastante elegante. Y eficiente. Un buen ejemplo de "¿por qué los programadores C no ponen más intenciones en sus identificadores? Porque les encanta ser lo suficientemente crípticos para parecer poderosos cuando no lo son". – TheBlastOne

Respuesta

33

Se counts number of 1's en representación binaria de n

+7

Me gusta cómo no habría necesitado que se le preguntara si la función se había llamado 'countBinaryOnes' en lugar de' f'. Además, +1. – Cam

+0

+1. Ver 2a aquí - http://gurmeetsingh.wordpress.com/2008/08/05/fast-bit-counting-routines/ – Dummy00001

+1

Elegancia de codificación: A +. Claridad de codificación: F. – Jay

3

Cuenta el número de iteraciones que se necesita para reducir n a 0 usando un archivo binario y.

+0

Sí, pero ¿de qué depende ese número de iteraciones? P Vlad lo golpeó. –

+0

La respuesta es como máximo 1: n & 0 – Amnon

+3

@Nick; buen punto. No pensé en esa explicación, así que solo estaba describiendo la mecánica en lugar de la intención. –

0

Podría ser que trata de devolver el número de bits significativos n? (No lo he pensado por completo ...)

+0

Aunque creo que la respuesta de @Vladimir es técnicamente precisa, me gusta más esta explicación. – Randolpho

+2

@Randolpho ¿Qué? Esta respuesta es incorrecta Dada la entrada 0b1000, devolvería 1, no 4 (la cantidad de dígitos binarios significativos - bits) –

+0

¿Qué significan los bits significativos? – Amnon

10

Está diseñado para mostrar la importancia de los comentarios.

+14

No, claramente no es así. Está destinado a mostrar la importancia de los buenos nombres de función. –

+2

Un nombre de función descriptiva podría considerarse un comentario. – JeremyP

+3

@JeremyP: No. – Cam

0

Muestra una forma de cómo no programar (para el conjunto de instrucciones x86), utilizando una instrucción de ensamblador intrínseco/en línea es más rápido y mejor para leer algo tan simple como este. (pero esto solo es cierto para una arquitectura x86 por lo que sé, no sé cómo es ARM o SPARC o algo más)

+1

¿Cuál es la instrucción de montaje que lo hace en un Freescale HCS08? : P –

+0

Creo que necesita justificar eso un poco más. – BobbyShaftoe

4

Es una solución (ahora obsoleta) para la falta de la instrucción POPCNT en cpu no militares.

5

La función TIENE LA INTENCIÓN de devolver el número de bits en la representación de n. Lo que se pierde en las otras respuestas es que la función invoca un comportamiento indefinido para los argumentos n < 0. Esto se debe a que la función quita el número un bit cada vez, comenzando desde el bit más bajo hasta el más alto. Para un número negativo, esto significa que el último valor de n antes de que termine el bucle (para enteros de 32 bits en 2-complemento) es 0x8000000. Este número es INT_MIN y ahora se utiliza en el bucle por última vez:

n = n&(n-1) 

Desafortunadamente, INT_MIN-1 es un desbordamiento y desbordamientos de invocar un comportamiento indefinido. No se requiere una implementación conforme para "abarcar" enteros, por ejemplo, puede emitir una trampa de desbordamiento o dejar todo tipo de resultados extraños.

+1

Contar bits de conjunto en una cantidad firmada generalmente no es lo que quiere hacer de todos modos. La función debería aceptar 'unsigned int'. –

Cuestiones relacionadas