Come si conta il numero di bit impostati in un numero in virgola mobile utilizzando le funzioni C?Come si conterebbe il numero di bit impostato in un numero in virgola mobile?
risposta
Intendi i bit impostati nella rappresentazione a precisione singola IEEE-754 di un numero? In tal caso, esegui il cast su int (sia float che int sono a 32 bit di larghezza) e esegui un numero di bit regolare: SO question #109023.
La trasmissione a int troncerà e convertirà, non ti darà la rappresentazione grezza. – bdonlan
Buon punto. Quindi una soluzione migliore sarebbe quella di unirlo o di galleggiare f; * (int *) & f –
Penso che Adrian volesse dire gettare il puntatore, non il valore. –
Se si vuole lavorare sulla rappresentazione bit a bit reale di un numero in virgola mobile, si dovrebbe fare qualcosa di simile:
float f; /* whatever your float is */
int i = *(int *)&f;
Quello che fa è prendere l'indirizzo del f
con l'operatore di indirizzo, &
. Questo indirizzo è di tipo float *
, un puntatore a un float. Quindi lo ricama con (int *)
, che dice "fai finta che questo puntatore non punti più a float
, ma ora punta a uno int
". Si noti che non cambia affatto il valore a f
. Quindi l'ultimo *
(o prima, dal momento che leggiamo da destra a sinistra) dereferenzia questo puntatore, che è un puntatore a un int
, e quindi restituisce un intero int
, a.k.a. con la stessa rappresentazione bitwise del float.
di fare il contrario (convertire e int i
di nuovo ad un float f
), fare il contrario:
f = *(float *)&i;
Se non erro, questa operazione non è definito dallo standard C, ma probabilmente funzionerà sulla maggior parte dei computer e compilatori. Non è definito perché ritengo che la reale rappresentazione in virgola mobile dei numeri sia dipendente dall'implementazione e possa essere lasciata alla CPU o al compilatore e quindi il valore di i
è quasi impossibile da prevedere dopo questa operazione (lo stesso vale per il valore di f
nell'operazione inversa). È notoriamente usato nella funzione di radice quadrata inversa di John Carmack per lo stesso scopo nefasto.
Ad ogni modo, se lo fai in codice reale, dovresti probabilmente fermarti a riflettere due volte su cosa stai cercando di fare e perché stai usando float
s per farlo. Tuttavia, se lo fai solo per curiosità, o se hai pensato a questi e sei sicuro del tuo design e dei tuoi metodi, fallo.
Sono portato a credere che tu sappia già come contare il numero di bit impostato in un numero intero regolare, poiché questo è un compito molto più semplice. Se non lo sai, il tuo compilatore (o il linguaggio C, non lo so nemmeno io) potrebbe avere una funzione per contare i bit, o potresti usare qualcosa dal meraviglioso sito web Bit-Twiddling Hacks, che ha modi per fare cose come questa con operazioni bit a bit (che dovrebbero essere piuttosto veloci).
Non è definito non solo a causa di ciò - GCC (in alcune configurazioni) avviserà ** il puntatore con puntatore tipo dereferencing interromperà le regole di aliasing rigoroso ** con una buona ragione, poiché in questo modo si rompe l'ipotesi (da ISO C che benefici prestazioni) che due puntatori a tipi distinti semplici (diversi da 'char') non puntano mai allo stesso oggetto. – ephemient
Dove sono i due indicatori qui? – sigjuice
'& f' e' (int *) & f' – ephemient
#include <stdio.h> /* for printf() */
#include <limits.h> /* for CHAR_BIT */
int main(void) {
/* union method */
{
/* a union can only be initialized for the first option in the union */
union { float f; char cs[sizeof(float)]; } const focs = { 1.0 };
int j,k;
int count = 0;
for (j = 0; j < sizeof(float); j++)
{
char const byte = focs.cs[j];
for (k = 0; k < CHAR_BIT; k++)
{
if ((1 << k) & byte)
{
count++;
}
}
}
printf("count(%2.1f) = %d\n", focs.f, count);
}
/* cast method */
{
float const f = 2.5;
int j,k;
int count = 0;
for (j = 0; j < sizeof(float); j++)
{
char const byte = ((char *)&f)[j];
for (k = 0; k < CHAR_BIT; k++)
{
if ((1 << k) & byte)
{
count++;
}
}
}
printf("count(%2.1f) = %d\n", f, count);
}
return 0;
}
Ho dimenticato l'hack del sindacato! Ma dovresti usare sizeof (float) invece di sizeof (int). Inoltre, int e float hanno le stesse dimensioni sulla maggior parte dei sistemi, ma non riesco a trovare nessuno standard che dica qualcosa sulle loro dimensioni relative (o qualcosa sulle dimensioni float), quindi non posso esserne sicuro - ma non sarebbe più bello avere solo 1 ciclo for() e usare invece un'unione di float e int? –
Questa è la cosa - penso che per quanto riguarda l'implementazione, sono quasi sempre gli stessi, ma non conosco nessuno standard che detta così, ed è per questo che l'ho fatto in questo modo. Potrei ancora comprimere i due loop facendo 'int i; int count = 0; for (i = 0; i <8 * sizeof (float); i ++) {if ((1 << (i% 8)) & focs.cs [i/8]) {count ++; }} ' – rampion
Anche se con questo (http://stackoverflow.com/questions/881894/is-char-guaranteed-to-be-exactly-8-bit-long-in-c) dovrei usare' CHAR_BIT' invece di 8 (anche se sono sicuro assumendo 'sizeof (char) == 1', dato che è per definizione). – rampion
una bella funzione per il conteggio impostati i bit in un intero di cui parla la prima risposta:
int NumberOfSetBits(int i)
{
i = i - ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
return ((i + (i >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
}
di utilizzarlo sul galleggiante si dovrebbe fare qualcosa di simile:
//...
float f;
//...
int numBitsOfF = NumberOfSetBits(*(int*) &f);
Grazie mille a tutti per il supporto –
The following function will find the number of bits in a 32-bit number. Just type case your float with integer and call this function by a cast
float f=3.14f;
count_bits(*(int *)&f);
int count_bits(int v)
{
// count the number of bits set in v
int c; // c accumulates the total bits set in v
int b=v;
for (c = 0; v; c++)
{
v &= v - 1; // clear the least significant bit set
}
//printf("No of bits in %d is %d\n",b,c);
return c;
}
- 1. Formato numero in virgola mobile
- 2. Reinterpretare il numero in virgola mobile nel numero intero
- 3. Come si verifica se un numero in virgola mobile è un numero intero in haskell?
- 4. Come si fa a arrotondare un numero in virgola mobile a un numero specificato di cifre?
- 5. Rappresentazione piacevole di un numero in virgola mobile in python
- 6. Formato numero in virgola mobile con zeri
- 7. bc troncare virgola mobile numero
- 8. Come si salva un numero in virgola mobile in 2 byte?
- 9. Posso confrontare e aggiungere un numero in virgola mobile a un numero intero in C?
- 10. Converti variabile in virgola mobile in numero intero?
- 11. numero di 1 in 32 bit numero
- 12. Come si conta il numero di bit zero in un numero intero?
- 13. Dato un numero, come trovare un numero più vicino in una serie di dati in virgola mobile
- 14. Libreria per virgola mobile in virgola mobile Math in .NET
- 15. Metodo più efficiente per generare un numero casuale con un numero fisso di bit impostato
- 16. Visualizzazione del numero a virgola mobile come percentuale senza modificare il valore del numero
- 17. JavaScript ha una precisione del numero a virgola mobile doppia?
- 18. Numero intero per byte con un numero dato di bit impostato
- 19. Conversione di un virgola mobile al relativo bit-segmenti
- 20. conversione in virgola mobile in virgola mobile a 32 bit in Java
- 21. Come convertire il numero intero in virgola mobile nella query di SQL Server?
- 22. Numero del bit non impostato rimasto del bit più significativo impostato?
- 23. Rappresentazione portatile del bit in virgola mobile C++?
- 24. Come memorizzare un numero in virgola mobile come testo senza perdere precisione?
- 25. Come per rilevare un numero in virgola mobile usando un'espressione regolare
- 26. C - arrotondamento in virgola mobile
- 27. È possibile determinare il numero di transizioni bit a bit in un numero intero a 8 bit?
- 28. Come convertire una rappresentazione di stringa di un numero in un numero in coldfusion?
- 29. abbinabili virgola mobile di Excel in Java
- 30. Converti virgola mobile in virgola mobile (SQL Server)
perché ti interessa? – AShelly
per misurare le prestazioni? –