Float 754 nach Hamming

29

Als Eingabe erhalten Sie eine ganze Zahl kim Bereich von -4503599627370496(−2 52 ) bis 4503599627370496(2 52 ). Wie allgemein bekannt , ganze Zahlen in diesem Bereich können Gleitkommazahlen als doppelte Genauigkeit repräsentieren genau werden.

Sie sollten Ausgabe das Hamming - Gewicht (Anzahl der Einsen) der Codierung von kin binary64 Format . Dies verwendet 1 Bit für das Vorzeichen, 11 Bit für den Exponenten (mit einem Offset codiert) und 52 Bit für die Mantisse. Einzelheiten finden Sie unter dem obigen Link.

Als Beispiel wird Zahl 22dargestellt als

0 10000000011 0110000000000000000000000000000000000000000000000000

Da es 5solche gibt , ist die Ausgabe 5.

Beachten Sie, dass Endianness das Ergebnis nicht beeinflusst. Sie können also die tatsächliche interne Darstellung von Werten mit doppelter Genauigkeit verwenden, um die Ausgabe zu berechnen.

Zusätzliche Regeln

Testfälle

22                ->   5
714               ->   6
0                 ->   0
1                 ->  10
4503599627370496  ->   5
4503599627370495  ->  55
1024              ->   3
-1024             ->   4
-4096             ->   5
1000000000        ->  16
-12345678         ->  16
Luis Mendo
quelle
1
Wollen Sie, dass Funktionen ihre Eingaben bereits im Gleitkommaformat akzeptieren können, binary64wenn sie wollen? Einige Leute (einschließlich ich selbst) interpretierten die Frage so, dass Funktionen Eingaben als Integer-Typ wie C akzeptieren müssen long. In C können Sie argumentieren, dass die Sprache für Sie konvertiert wird, genau wie wenn Sie anrufen sqrt((int)foo). Es gibt jedoch einige x86-Maschinencode-asm-Antworten (wie codegolf.stackexchange.com/a/136360/30206 und meine), die beide davon ausgehen, dass wir 64-Bit-Integer-Eingaben akzeptieren müssen. Das Akzeptieren eines binary64Wertes würde 5 Bytes sparen.
Peter Cordes
Wenn ja, dann ist all das Zeug über begrenzte Reichweite nur für den Fall, dass jemand die Umwandlung in ein binäres 64-Bit-Muster selbst hacken wollte, anstatt Typ-Punning? Oder für Sprachen ohne Tippfehler? Hmm, eine interessante Herausforderung könnte darin bestehen, den Exponenten und die Mantisse von a binary64als Ganzzahlen zur Basis 2 zu addieren . Wenn Sie sie trotzdem separat behandeln müssen, kann es sich lohnen, etwas anderes als Typ-Wortspiel zu tun und alle Bits in einer Schleife zu durchlaufen.
Peter Cordes
2
@PeterCordes Ja, Sie können eine Gleitkommazahl eingeben. Der begrenzte Bereich soll sicherstellen, dass die Gleitkommadarstellung korrekt ist
Luis Mendo
OK danke. Ich vermute, Sie wollten die Option verlassen, eine Funktion zu schreiben, die a benötigt long, und konnten daher keine binary64-Anweisung verwenden double, da nicht alle Doubles Ganzzahlen sind. Aber alle ganzzahligen doubles können longbis zu den Grenzen von in und zurück konvertiert werden long. (Sie weisen darauf hin, dass das Gegenteil nicht zutrifft. Sie erhalten die nächstgelegene Darstellung double, wenn Sie den Standardrundungsmodus annehmen.) Auf jeden Fall war dies eine absolut gültige Methode, um die Frage zu stellen. Ich habe es nur nicht sorgfältig gelesen>. <
Peter Cordes
"Beachten Sie, dass Endianness das Ergebnis nicht beeinflusst. Sie können also die tatsächliche interne Darstellung von Werten mit doppelter Genauigkeit verwenden, um die Ausgabe zu berechnen." es sei denn, Ihr Computer verwendet kein IEEE-Gleitkommaformat ...
Jerry Jeremiah

Antworten:

8

MATL , 5 Bytes

3Z%Bz

Probieren Sie es online!

Genaue Transliteration meiner MATLAB-Antwort. Beachten Sie, dass Eingabe und Ausgabe implizit sind. -2 Bytes dank Luis Mendo.

3Z%   % Typecast: changes input (implicitly taken and converted to double) to uint64 without changing underlying bits
B     % Convert integer to array of 1s and 0s
z     % Count nonzero entries
Sanchises
quelle
33

x86_64-Maschinensprache (Linux), 16 Byte

0:       f2 48 0f 2a c7          cvtsi2sd %rdi,  %xmm0
5:       66 48 0f 7e c0          movq     %xmm0, %rax
a:       f3 48 0f b8 c0          popcnt   %rax,  %rax
f:       c3                      retq

Akzeptiert einen einzelnen 64-Bit-Integer-Parameter in RDI, konvertiert ihn in einen Gleitkommawert in XMM0, speichert diese Bits wieder in RAXund berechnet dann das Hamming-Gewicht von RAX, wobei das Ergebnis in belassen wird , RAXdamit es an den Aufrufer zurückgegeben werden kann.

Erfordert einen Prozessor, der die POPCNTAnweisung unterstützt , beispielsweise Intel Nehalem, AMD Barcelona und spätere Mikroarchitekturen.

Um es online auszuprobieren! , kompilieren Sie das folgende C-Programm und führen Sie es aus:

#include<stdio.h>
const char g[]="\xF2\x48\x0F\x2A\xC7\x66\x48\x0F\x7E\xC0\xF3\x48\x0F\xB8\xC0\xC3";
#define f(x) ((int(*)(long))g)(x)

int main(int a){
  printf("%d\n",f(22));
  printf("%d\n",f(714));
  printf("%d\n",f(0));
  printf("%d\n",f(1));
  printf("%d\n",f(4503599627370496L));
  printf("%d\n",f(4503599627370495L));
  printf("%d\n",f(1024));
  printf("%d\n",f(-1024));
  printf("%d\n",f(-4096));
  printf("%d\n",f(1000000000));
  printf("%d\n",f(-12345678));
}
Ceilingcat
quelle
2
+1, das richtige Werkzeug für den Job! Dies könnte das einzige Mal sein, dass x86 legitimerweise mit Golfsprachen konkurrieren oder Jelly schlagen kann. :)
DJMcMayhem
2
Ew, AT & T-Syntax? Sie können objdump -drwC -Mintelzum Zerlegen in Intel-Syntax verwenden. Wenn Sie einen Zeiger in einem Register hätten, den Sie zum Speichern / Neuladen verwenden könnten, könnten Sie Bytes mit movaps [rsi], xmm0/ speichern popcnt rax, [rsi]. (movaps ist nur 3 Bytes, 2 kürzer als movq.) Aber das hilft hier nicht, weil [rsp-24]2 zusätzliche Bytes benötigt werden (SIB, wenn RSP als Basis verwendet wird, plus disp8). Und diese zusätzlichen Bytes werden sowohl im Speicher als auch beim Neuladen benötigt. Na ja, ich dachte, ich sah eine Ersparnis, aber nein: /
Peter Cordes
Ich habe 4 Bytes mit einer benutzerdefinierten Aufrufkonvention gespeichert . Oder speichern Sie mithilfe von x87-Anweisungen immer noch 2 Bytes mit derselben Aufrufkonvention wie dieser.
Peter Cordes
1
@ DJMcMayhem: Vielleicht nicht das einzige Mal. Bei der Extreme Fibonacci-Herausforderung gibt es immer noch keine golfsprachigen Antworten (die ersten 1000 Stellen von Fib (1 Milliarde) und meine x86-Maschinencode-Antwort (105 Bytes schnell oder 101 Bytes, die in 5 Minuten statt 1 Minute ausgeführt werden). ist nicht viel größer als einige der anderen Antworten, und sie sind alle in Sprachen mit erweiterten Ganzzahlen eingebaut.
Peter Cordes
2
Oder eine einfachere Herausforderung (und ohne Leistungsanforderung): Chroma-Key-Blending einer Reihe von ganzen Zahlen . Meine Maschinencode-Antwort ist halb so lang wie die Pyth-Antwort.
Peter Cordes
11

C (GCC) , 82 68 Bytes

9 Bytes dank Neil.

böse Fließkomma-Bit-Level-Hacking

s;f(long n){double d=n;n=*(long*)&d;for(s=0;n;n*=2)s+=n<0;return s;}

Probieren Sie es online!

Undichte Nonne
quelle
Ich wusste, dass du der Erste sein würdest, ich habe die Sprache einfach nicht erwartet :-D
Luis Mendo
@ LuisMendo Ich dachte nur, dass es in dieser Sprache praktisch wäre ... Ich kenne keine anderen Sprachen, die das können
Leaky Nun
2
Speichern Sie 9 Bytes, indem Sie in die andere Richtung verschieben: ... ;long l=... ;l*=2;)s+=l<0;...
Neil
1
Dies setzt natürlich eine C-Implementierung mit 64-Bit voraus long. Es funktioniert unter x86-64 Linux, würde aber unter Windows fehlschlagen. Ich würde vorschlagen, "gcc mit 64-Bit long" zu sagen , da gcc auf vielen Plattformen läuft, viele davon mit unterschiedlichen ABIs.
Peter Cordes
1
@Peters Kommentar ist, warum ich "LP64" in einer Bearbeitung hinzugefügt habe. Ich habe auch den anderen Text in einer meiner Meinung nach logischeren Reihenfolge neu angeordnet. Ich vermute, Sie mochten diese Änderung nicht und haben sie zurückgesetzt, aber LP64 ist ein Standardbegriff, der das ABI beschreibt, bei dem Longs und Pointer 64-Bit-Werte sind (im Vergleich zu ILP64, bei dem Ints ebenfalls 64-Bit sind, oder LLP64). wie unter Windows verwendet, wo nur long longs und Pointer 64-Bit und longs noch 32-Bit sind). Vielleicht hätte ich mehr Erklärung oder einen Inline-Link zum entsprechenden Wikipedia-Artikel hinzufügen sollen.
Cody Grey
8

Python 3 , 72 71 Bytes

1 Byte danke an Lynn.

lambda n:n and(bin(1020+len(bin(abs(n))))+bin(abs(n))).count('1')-(n>0)

Probieren Sie es online!

Erläuterung

Das binary64-Format besteht aus drei Komponenten:

  • Das erste Bit ist das Vorzeichenbit, 1wenn die Zahl negativ ist
  • Die nächsten 11 Bits speichern den Exponenten mit 1023 addierten
  • Die nächsten 52 Bits speichern den Signifikanten oder die Mantisse.
Undichte Nonne
quelle
n and(…)-(n>0)ist ein Byte kürzer, nein?
Lynn
Oder int-> float oder irgendwelche floats überhaupt.
user2357112 unterstützt Monica
8

C (gcc) , 47 Bytes

f(double n){n=__builtin_popcountl(*(long*)&n);}

Dies ist nicht portabel; Es wurde mit gcc 7.1.1 unter x86_64 unter Linux ohne Compiler-Flags getestet.

Probieren Sie es online!

Dennis
quelle
1
Die Eingabe muss eine Ganzzahl sein. Oder ist es in Ordnung, dass der Anrufer dies durch implizite Konvertierung von longnach doublean der Anrufstelle erledigt?
Peter Cordes
1
Auch auf einen glücklichen Zufall von Compiler Verhalten unter Berufung passieren lassen nin raxmit nicht optimierten Code ist ziemlich geschmacklos. Es funktioniert nicht mehr, wenn Sie es aktivieren -O3. Es ist also nicht nur gcc im Allgemeinen, sondern gcc auf x86-64 mit 64-Bit longund deaktivierter Optimierung. Wenn Sie all diese Anforderungen in Ihre Antwort aufnehmen, würde ich positiv stimmen. Ich gehe davon aus, dass es Plattformen gibt, die von gcc unterstützt werden und 64-Bit haben, longaber das popcountlErgebnis in einem anderen Register als dem Rückgabewertregister hinterlassen .
Peter Cordes
1
Ich habe eine ganze Zahl im mathematischen Sinne genommen. Ich habe die Spezifikationen meiner Testumgebungen hinzugefügt, da ich nicht sicher bin, ob gcc, x86-64 und 64-Bit-Longs ausreichen. Zumindest auf x86 funktionieren Funktionen ohne Rückgabe jedoch häufiger mit gcc (und tcc).
Dennis
Ja, ich habe die Frage gerade noch einmal gelesen und stimme zu, dass doublees in Ordnung sein sollte , das Argument als zu akzeptieren . Es sagt nichts darüber aus, dass die Funktion es im base2-Format akzeptieren muss. Und ja, verschiedene Versionen von gcc könnten unterschiedlichen Code ausgeben, das ist auch wichtig. ( Unterhaltsame Tatsache: Ohne -mpopcntwird gcc das popcntinsn nicht verwenden und gibt eine Folge von Anweisungen aus, um es zu emulieren. Einige Architekturen haben überhaupt keine popcnt-Anweisung, müssen also __builtin_popcountlimmer eine Folge von insns verwenden.)
Peter Cordes
Ja, viele (die meisten?) __builtin_*Funktionen haben Vorgängerversionen, um das Generieren illegaler Anweisungen zu vermeiden. -march=nativeVerwendet popcntqnur, wenn es verfügbar ist.
Dennis
6

C (gcc) 63 Bytes

f(double d){long s=0,n=*(long*)&d;for(;n;n*=2)s+=n<0;return s;}

Diese Lösung basiert auf der Antwort von @ LeakyNun, aber da er seine eigene Antwort nicht verbessern möchte, poste ich hier eine Golfversion.

Probieren Sie es online aus


quelle
2
Ich bezweifle sehr, dass jemand seine Antwort nicht verbessern möchte .
Mr. Xcoder
1
@ Mr.Xcoder. Ok, ich behalte das hier, bis er seine eigene Antwort bearbeitet. Wenn er nicht bearbeiten möchte, bleibt dies hier. Ich habe diese Verbesserung als Kommentar zu seiner Antwort veröffentlicht und er hat sie abgelehnt.
1
Ich denke, die Eingabe muss ein Integer-Typ und kein Real sein.
Ceilingcat
3
@ThePirateBay Ich habe Ihren Kommentar zu meiner Antwort nicht gesehen und sehe ihn jetzt immer noch nicht.
Undichte Nonne
9
Die Entscheidung, Verbesserungen vorzuschlagen oder Ihre eigene Antwort zu posten, liegt bei Ihnen, aber 6 Minuten sind kaum eine Stunde .
Dennis
5

C #, 81 70 68 Bytes

d=>{unsafe{long l=*(long*)&d,s=0;for(;l!=0;l*=2)s-=l>>63;return s;}}

Sparen Sie 11 Bytes dank @Leaky Nun.
2 Bytes dank @Neil gespeichert.

Probieren Sie es online! Verwendet System.BitConverter.DoubleToInt64Bitsanstelle des unsafeCodes, da ich TIO nicht dazu bringen konnte, damit zu arbeiten.

Voll / Formatierte Version:

namespace System
{
    class P
    {
        static void Main()
        {
            Func<double, long> f = d =>
            {
                unsafe
                {
                    long l = *(long*)&d, s = 0;

                    for (; l != 0; l *= 2)
                        s -= l >> 63;
                    return s;
                }
            };

            Console.WriteLine(f(22));
            Console.WriteLine(f(714));
            Console.WriteLine(f(0));
            Console.WriteLine(f(1));
            Console.WriteLine(f(4503599627370496));
            Console.WriteLine(f(4503599627370495));
            Console.WriteLine(f(1024));
            Console.WriteLine(f(-1024));
            Console.WriteLine(f(-4096));
            Console.WriteLine(f(1000000000));
            Console.WriteLine(f(-12345678));

            Console.ReadLine();
        }
    }
}
TheLethalCoder
quelle
for(;l!=0;l*=2)und du brauchst nicht den Dreistoff
Undichte Nonne
@LeakyNun Danke. Ich habe mich lange am Kopf gekratzt.
TheLethalCoder
Kannst du verwenden s-=l>>31?
Neil
@Neil Scheint nicht zu funktionieren. Ich nehme an, Sie wollen ersetzen s+=l<0?1:0?
TheLethalCoder
Mein Fehler; list eine lange, so braucht es s-=l>>63?
Neil
4

Python 2 , 69 Bytes

-12 Byte, dank nur @ ASCII

lambda n:bin(*unpack('Q',pack('d',n))).count('1')
from struct import*

Probieren Sie es online!

Totes Opossum
quelle
1
71 Bytes
ASCII
1
Wenn Sie 76 Bytes vorgehen, empfehle ich allerdings nur die ASCII-
Methode
@ Mr.Xcoder das !wird nicht benötigt, da die Bytereihenfolge hier keine Rolle spielt
ASCII
1
69 Bytes
ASCII
@ Nur ASCII Packen Sie die entpackten. Danke: D
Dead Possum
4

JavaScript (ES6), 81 80 77 Byte

f=
n=>new Uint8Array(Float64Array.of(n).buffer).map(g=i=>i&&g(i^i&-i,x++),x=0)|x
<input oninput=o.textContent=f(this.value)><pre id=o>0

Bearbeiten: 1 Byte dank @Arnauld gespeichert. 3 Bytes gespart dank @DocMax.

Neil
quelle
Könnten Sie g(i^i&-i,x++)für -1 Byte tun ?
Arnauld
@Arnauld Ich habe mich gefragt, ob es ein bisschen mehr Golf gibt, danke, dass du es gefunden hast!
Neil
1
-3 mehr, wenn Sie ersetzen new Float64Array([n])durchFloat64Array.of(n)
DocMax
4

x86-64-Maschinencode, 12 Byte für int64_t Eingabe

6 Bytes für double Eingabe

Benötigt die popcntISA-Erweiterung (CPUID.01H:ECX.POPCNT [Bit 23] = 1 ).

(Oder 13 Bytes, wenn das Ändern des Arg an Ort und Stelle das Schreiben aller 64-Bits erfordert, anstatt Müll in den oberen 32 zu belassen. Ich denke, es ist vernünftig zu argumentieren, dass der Aufrufer wahrscheinlich nur die niedrigen 32b und x86 Null laden möchte -Erweitert sich implizit mit jeder 32-Bit-Operation von 32 auf 64. Trotzdem wird der Aufrufer davon abgehalten, add rbx, [rdi]etwas zu tun oder so.)

x87-Anweisungen sind kürzer als die offensichtliche SSE2 cvtsi2sd/ movq(in der Antwort von @ ceilingcat verwendet ), und ein [reg]Adressierungsmodus ist so groß wie einereg : nur ein mod / rm-Byte.

Der Trick bestand darin, einen Weg zu finden, wie der Wert im Speicher übergeben werden kann, ohne dass zu viele Bytes für die Adressierungsmodi benötigt werden. (z. B. ist das Weitergeben des Stapels nicht so toll.) Glücklicherweise erlauben die Regeln Lese- / Schreib-Args oder separate Ausgabeargs , sodass ich den Aufrufer einfach dazu bringen kann, mir einen Zeiger auf den Speicher zu übergeben, den ich schreiben darf.

Aufrufbar von C mit der Signatur: void popc_double(int64_t *in_out); Nur die niedrigen 32b des Ergebnisses sind gültig, was für C vielleicht seltsam, für asm aber natürlich ist. (Um dies zu beheben, ist ein REX-Präfix im endgültigen Speicher ( mov [rdi], rax) erforderlich , also ein weiteres Byte.) Ändern Sie unter Windows rdizu rdx, da Windows das x86-64-System-V-ABI nicht verwendet.

NASM-Auflistung. Der TIO-Link enthält den Quellcode ohne Demontage.

  1  addr    machine      global popcnt_double_outarg
  2          code         popcnt_double_outarg:
  3                           ;; normal x86-64 ABI, or x32: void pcd(int64_t *in_out)
  4 00000000 DF2F             fild qword  [rdi]    ; int64_t -> st0
  5 00000002 DD1F             fstp qword  [rdi]    ; store binary64, using retval as scratch space.
  6 00000004 F3480FB807       popcnt rax, [rdi]
  7 00000009 8907             mov    [rdi], eax    ; update only the low 32b of the in/out arg
  8 0000000B C3               ret
    # ends at 0x0C = 12 bytes

Probieren Sie es online! Beinhaltet a_start Testprogramm, das ihm einen Wert übergibt und mit dem Rückgabewert exit status = popcnt beendet wird. (Öffnen Sie die Registerkarte "Debug", um sie anzuzeigen.)

Das Übergeben separater Eingabe- / Ausgabezeiger würde ebenfalls funktionieren (rdi und rsi in der x86-64-SystemV-ABI), aber dann können wir die 64-Bit-Eingabe nicht vernünftigerweise zerstören oder die Notwendigkeit eines 64-Bit-Ausgabepuffers genauso einfach rechtfertigen, während nur die geschrieben wird niedrig 32b.

Wenn wir argumentieren möchten, dass wir einen Zeiger auf die ganze Zahl der Eingabe nehmen und sie zerstören können, während wir die Ausgabe zurückgeben rax, lassen Sie einfach das mov [rdi], eaxfrom weg popcnt_double_outargund bringen Sie es auf 10 Bytes herunter.


Alternative ohne alberne Calling-Convention-Tricks, 14 Bytes

Verwenden Sie den Stapel als Arbeitsfläche, pushum ihn dorthin zu bringen. Verwenden Sie push/, popum Register in 2 Bytes anstelle von 3 für zu kopieren mov rdi, rsp. ( [rsp]Benötigt immer ein SIB-Byte, es lohnt sich also, 2 Byte für das Kopieren auszugeben, rspbevor drei Anweisungen es verwenden.)

Anruf von C mit dieser Signatur: int popcnt_double_push(int64_t);

 11                               global popcnt_double_push
 12                               popcnt_double_push:
 13 00000040 57                       push   rdi         ; put the input arg on the stack (still in binary integer format)
 14 00000041 54                       push   rsp         ; pushes the old value (rsp updates after the store).
 15 00000042 5A                       pop    rdx         ; mov      rdx, rsp
 16 00000043 DF2A                     fild   qword [rdx]
 17 00000045 DD1A                     fstp   qword [rdx]
 18 00000047 F3480FB802               popcnt rax,  [rdx]
 19 0000004C 5F                       pop    rdi         ; rebalance the stack
 20 0000004D C3                       ret
    next byte is 0x4E, so size = 14 bytes.

Eingabe im doubleFormat übernehmen

Die Frage besagt nur, dass es sich um eine Ganzzahl in einem bestimmten Bereich handelt und nicht, dass es sich um eine binäre Ganzzahldarstellung zur Basis 2 handeln muss. Das Akzeptieren von doubleEingaben macht die Verwendung von x87 überflüssig. (Es sei denn, Sie verwenden eine benutzerdefinierte Aufrufkonvention, bei der doubles in x87-Registern übergeben wird. Anschließend in der roten Zone unter dem Stapel speichern und von dort aus einfügen.)

11 Bytes:

 57 00000110 66480F7EC0               movq    rax, xmm0
 58 00000115 F3480FB8C0               popcnt  rax, rax
 59 0000011A C3                       ret

Wir können jedoch den gleichen Trick wie zuvor verwenden, um eine 6-Byte-Version zu erstellen: int pcd(const double&d);

 58 00000110 F3480FB807               popcnt  rax, [rdi]
 59 00000115 C3                       ret

6 Bytes .

Peter Cordes
quelle
4

Perl 5 , 33 32 + 1 (-p) = 34 33 Bytes

1 Byte dank hobbs gespeichert

$_=(unpack"B*",pack d,$_)=~y/1//

Probieren Sie es online!

Xcali
quelle
Sie können 1 Byte sparen, indem Sie dein Barewort ( pack d,$_anstelle von pack"d",$_)
erstellen
3

MATLAB, 36 Bytes

@(n)nnz(de2bi(typecast(n,'uint64')))

Verwenden der Tatsache, dass de2binicht nur kürzer als dec2bin, sondern auch ein Ergebnis in Einsen und Nullen anstelle von ASCII 48, 49 bereitgestellt wird.

Sanchises
quelle
3

Java (64, 61, 41 Byte)

Ganz einfach mit der Standardbibliothek (Java SE 5+):

int f (long n) {return Long. bitCount (Double. doubleToLongBits (n));}

Beitrag von Kevin Cruijssen (Java SE 5+):

int f(Long n){return n.bitCount(Double.doubleToLongBits(n));}

Beitrag von Kevin Cruijssen (Java SE 8+, Lambda-Funktion):

n->n.bitCount(Double.doubleToLongBits(n))
Nayuki
quelle
Schön gemacht! :-)
Undichte Nonne
1
Schöne Antwort, +1 von mir. Sie können drei Bytes Golf spielen, indem Sie den Parameter as Long nund use n.bitCount(...)anstelle von verwenden Long.bitCount(...). Wenn Sie Java 8+ verwenden, können Sie außerdem auf n->n.bitCount(Double.doubleToLongBits(n))( 41 Byte )
Kevin Cruijssen,
2

Um einen anderen, sichereren Ansatz als den von TheLethalCoder zu versuchen , habe ich mir das ausgedacht (schade, dass C # so lange Methodennamen hat):

C # (.NET Core) , 76 + 13 Bytes

d=>Convert.ToString(BitConverter.DoubleToInt64Bits(d),2).Split('1').Length-1

Probieren Sie es online!

Die Byteanzahl umfasst 13 Bytes für using System;. Zuerst muss ich das doublein ein konvertieren long, das die gleiche binäre Darstellung hat, dann kann ich es in ein binäres konvertieren string, und dann zähle ich das 1s, indem ich den String aufspalte und die Teilstrings minus 1 zähle.

Charlie
quelle
Gute Alternative, aber Sie müssen die usingin Ihre Byteanzahl aufnehmen.
TheLethalCoder
Verwenden Sie Linq für 95 Bytes nur ein paar mehr: namespace System.Linq;{d=>Convert.ToString(BitConverter.DoubleToInt64Bits(d),2).Count(c=>c>48)}. Obwohl ich es nicht getestet habe, sollte es funktionieren.
TheLethalCoder
@TheLethalCoder funktioniert, aber ich habe versucht, Linq zu meiden, sodass ich keine zweite usingDirektive hinzufügen musste .
Charlie
1
Wenn Sie die zweite hinzufügen, ist das, wenn namespacees praktisch ist. Aber ja, in diesem Fall war es etwas billiger, Linq zu meiden. Wollte nur mit seiner Herangehensweise kommentieren, falls Sie Ideen hatten, wie man es verkürzen kann, um Ihnen Bytes zu sparen.
TheLethalCoder
@TheLethalCoder, Sum(c=>c&1)ist kürzer. OderSum()-768
Peter Taylor
1

Gleichstrom, 79 Bytes

[pq]su[-1r]st0dsb?dd0=u0>tsa[1+]ss[la2%1=slb1+sblad2/sa1<r]dsrxlb1022+sa0lrx+1-

Die Ausgabe bleibt oben auf dem Stapel.
Ich werde später eine Erklärung hinzufügen.

Probieren Sie es online!

Beachten Sie, dass negative Zahlen durch vorangestellt sind _, nicht -.

poi830
quelle
1

C 67 Bytes

int i;g(char*v){int j=v[i/8]&1<<i%8;return!!j+(++i<64?g(v):(i=0));}

Kontrollcode und Ergebnisse

#define R     return
#define u32 unsigned
#define F        for
#define P     printf

int main()
{/*           5   6 0 10                5               55    3      4       16*/
 double v[]={22,714,0,1 ,4503599627370496,4503599627370495,1024, -1024, -12345678};
 int i; 

 F(i=0;i<9;++i)
     P("%f = %d\n", v[i], g(&v[i]));
 R 0;
}

>tri4
22.000000 = 5
714.000000 = 6
0.000000 = 0
1.000000 = 10
4503599627370496.000000 = 5
4503599627370495.000000 = 55
1024.000000 = 3
-1024.000000 = 4
-12345678.000000 = 16
RosLuP
quelle