Pływak 754 do Hamminga

29

Jako dane wejściowe zostanie podana liczba całkowita kz zakresu od -4503599627370496(-2 52 ) do 4503599627370496(2 52 ). Jak dobrze wiadomo , liczby całkowite w tym zakresie można przedstawić dokładnie jako wartości zmiennoprzecinkowe podwójnej precyzji.

Zalecana moc na wadze Hamminga (liczba jedynek) z kodowaniem kw formacie binary64 . Wykorzystuje to 1 bit dla znaku, 11 bitów dla wykładnika wykładnika (zakodowanych z przesunięciem) i 52 dla mantysy; zobacz powyższy link, aby uzyskać szczegółowe informacje.

Na przykład liczba 22jest reprezentowana jako

0 10000000011 0110000000000000000000000000000000000000000000000000

Ponieważ są 5takie, wynikiem jest 5.

Zauważ, że endianness nie wpływa na wynik, więc możesz bezpiecznie użyć rzeczywistej wewnętrznej reprezentacji wartości podwójnej precyzji w celu obliczenia wyniku.

Dodatkowe zasady

Przypadki testowe

22                ->   5
714               ->   6
0                 ->   0
1                 ->  10
4503599627370496  ->   5
4503599627370495  ->  55
1024              ->   3
-1024             ->   4
-4096             ->   5
1000000000        ->  16
-12345678         ->  16
Luis Mendo
źródło
1
Czy chcesz, aby funkcje mogły akceptować swoje dane wejściowe w binary64formacie zmiennoprzecinkowym , jeśli chcą? Niektórzy ludzie (w tym ja, początkowo) zostały interpretacji pytanie, wymagając, aby zaakceptować funkcje wejść jako typ C na całkowitą podobnego long. W C możesz argumentować, że język zostanie dla ciebie przekonwertowany, tak jak podczas rozmowy sqrt((int)foo). Ale istnieją odpowiedzi ASM na kod maszynowy x86 (takie jak codegolf.stackexchange.com/a/136360/30206 i moje), które zakładały, że musimy zaakceptować 64-bitowe liczby całkowite. Zaakceptowanie binary64wartości pozwoliłoby zaoszczędzić 5 bajtów.
Peter Cordes
Jeśli tak, to wszystkie te rzeczy o ograniczonym zasięgu są na wypadek, gdyby ktoś chciał zhakować konwersję do binarnego 64-bitowego wzorca zamiast pisowni? Lub dla języków bez pisowni? Hmm, ciekawym wyzwaniem może być dodanie wykładnika i mantysy binary64jako liczb całkowitych base2. Jeśli mimo to musisz poradzić sobie z nimi osobno, może warto zrobić coś innego niż pisanie na klawiaturze i zapętlić wszystkie bity.
Peter Cordes
2
@PeterCordes Tak, można wprowadzić liczbę zmiennoprzecinkową. Ograniczonym zasięgiem jest upewnienie się, że reprezentacja zmiennoprzecinkowa jest dokładna
Luis Mendo
Ok dzięki. longWydaje mi się, że chciałeś zostawić opcję napisania funkcji, która zajmuje , więc nie możesz po prostu powiedzieć binarnego64 double, ponieważ nie wszystkie liczby podwójne są liczbami całkowitymi. Ale wszystkie wartości całkowite doublemogą być konwertowane do longiz powrotem, do granic long. (Jak zauważyłeś, odwrotność nie jest prawdą. Otrzymujesz najbliższy reprezentowalny double, zakładając domyślny tryb zaokrąglania). W każdym razie był to całkowicie prawidłowy sposób postawienia pytania; Po prostu nie przeczytałem go dokładnie>. <
Peter Cordes,
„Pamiętaj, że endianizm nie wpływa na wynik, więc możesz bezpiecznie użyć rzeczywistej wewnętrznej reprezentacji wartości podwójnej precyzji w celu obliczenia wyniku”. chyba że twoja maszyna nie używa formatu zmiennoprzecinkowego IEEE ...
Jerry Jeremiah

Odpowiedzi:

8

MATL , 5 bajtów

3Z%Bz

Wypróbuj online!

Dokładna transliteracja mojej odpowiedzi MATLAB. Zauważ, że dane wejściowe i wyjściowe są niejawne. -2 bajty dzięki Luisowi 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
źródło
33

język maszynowy x86_64 (Linux), 16 bajtów

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

Akceptuje pojedynczy 64-bitowy parametr liczby całkowitej RDI, konwertuje go na wartość zmiennoprzecinkową w XMM0, przechowuje te bity z powrotem RAX, a następnie oblicza ciężar Hamminga RAX, pozostawiając wynik, RAXaby mógł zostać zwrócony dzwoniącemu.

Wymaga procesora obsługującego POPCNTinstrukcję, którym byłby Intel Nehalem, AMD Barcelona i późniejsze mikroarchitekty.

Aby Spróbuj online! , skompiluj i uruchom następujący program C:

#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));
}
sufitowy
źródło
2
+1, odpowiednie narzędzie do pracy! To może być jedyny czas, w którym x86 może legalnie konkurować z językami golfowymi lub pokonać Jelly. :)
DJMcMayhem
2
Ew, składnia AT&T? Możesz użyć objdump -drwC -Minteldo dezasemblacji w składni Intela. Jeśli masz w rejestrze wskaźnik, którego możesz użyć do przechowywania / przeładowywania, możesz zapisać bajty za pomocą movaps [rsi], xmm0/ popcnt rax, [rsi]. (movaps ma tylko 3 bajty, 2 krótsze niż movq.) Ale to nie pomaga tutaj, ponieważ [rsp-24]wymaga 2 dodatkowych bajtów (SIB z użycia RSP jako podstawy plus disp8). Te dodatkowe bajty są potrzebne zarówno w sklepie, jak i podczas ponownego ładowania. No cóż, myślałem, że widziałem oszczędność, ale nie: /
Peter Cordes
I zapisywane 4 bajty z konwencją zwyczaj wywołującego . Lub nadal zapisuj 2 bajty z taką samą konwencją wywoływania, jak przy użyciu instrukcji x87.
Peter Cordes
1
@DJMcMayhem: Może nie jedyny raz. Nadal nie ma odpowiedzi w języku golfowym na wyzwanie Extreme Fibonacciego (wydrukuj pierwsze 1000 cyfr Fib (1 miliard) i moją odpowiedź na kod maszynowy x86 (105 bajtów szybko lub 101 bajtów, które działają w 5 minut zamiast 1 minuty) jest niewiele większy niż niektóre inne odpowiedzi i wszystkie są w językach z wbudowanymi liczbami całkowitymi o rozszerzonej precyzji.
Peter Cordes
2
Lub prostsze wyzwanie (i bez wymagania wydajności), kluczowanie kolorem mieszanie szeregu liczb całkowitych . Moja odpowiedź na kod maszynowy jest o połowę krótsza od odpowiedzi na pyth.
Peter Cordes
11

C (gcc) , 82 68 bajtów

9 bajtów dzięki Neilowi.

hakowanie złego zmiennoprzecinkowego poziomu bitowego

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

Wypróbuj online!

Leaky Nun
źródło
Wiedziałem, że będziesz pierwszy, po prostu nie spodziewałem się języka :-D
Luis Mendo
@LuisMendo Właśnie pomyślałem, że będzie to wygodne w tym języku ... Nie znam innych języków, które mogą to zrobić
Leaky Nun
2
Zaoszczędź 9 bajtów, przesuwając w drugą stronę: ... ;long l=... ;l*=2;)s+=l<0;...
Neil
1
To oczywiście wymaga implementacji języka C w wersji 64-bitowej long. Działa na Linuksie x86-64, ale nie działa w systemie Windows. Sugeruję powiedzenie „gcc z wersją 64-bitową long”, ponieważ gcc działa na wielu platformach, wiele z nich z różnymi ABI.
Peter Cordes,
1
@ Komentarz Petera mówi, dlaczego dodałem „LP64” w edycji. Zmieniłem także drugi tekst w bardziej logicznej kolejności. Myślę, że nie podobała ci się ta zmiana i wycofałeś ją, ale LP64 jest standardowym terminem opisującym ABI, w którym długie i wskaźniki są wartościami 64-bitowymi (w porównaniu do ILP64, gdzie int są również 64-bitowe lub LLP64, używane w systemie Windows, w którym tylko długie długie i wskaźniki są 64-bitowe, a długie wciąż są 32-bitowe). Może powinienem dodać więcej wyjaśnień lub link do odpowiedniego artykułu w Wikipedii.
Cody Gray
8

Python 3 , 72 71 bajtów

1 bajt dzięki Lynn.

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

Wypróbuj online!

Wyjaśnienie

Format binary64 składa się z trzech elementów:

  • pierwszy bit jest bitem znaku, czyli 1jeśli liczba jest ujemna
  • następne 11 bitów przechowuje wykładnik z dodanym 1023
  • następne 52 bity przechowują znaczenie lub mantysę.
Leaky Nun
źródło
n and(…)-(n>0)jest bajt krótszy, nie?
Lynn
Lub int-> float, lub dowolne dowolne floaty, jeśli o to chodzi.
user2357112 obsługuje Monikę
8

C (gcc) , 47 bajtów

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

To nie jest przenośne; został przetestowany z gcc 7.1.1 na x86_64 z systemem Linux, bez flag kompilatora.

Wypróbuj online!

Dennis
źródło
1
Dane wejściowe muszą być liczbą całkowitą. Czy jest w porządku, aby pozwolić osobie dzwoniącej poradzić sobie z tym poprzez niejawną konwersję longna doublew witrynie wywołującej?
Peter Cordes,
1
Ponadto, opierając się na przywry zachowania kompilatora wydarzy zostawić nw raxz un-zoptymalizowany kod jest dość kiepskie. Zepsuje się, jeśli włączysz -O3, więc nie jest to tylko gcc w ogóle, to gcc na x86-64 z 64-bitami longz wyłączoną optymalizacją. Jeśli uwzględnisz wszystkie te wymagania w swojej odpowiedzi, głosuję. Zakładam, że istnieją platformy obsługujące gcc, które mają 64-bit, longale zdarza się, że pozostawiają popcountlwynik w rejestrze innym niż rejestr wartości zwracanej.
Peter Cordes
1
Wziąłem liczbę całkowitą w sensie matematycznym. Dodałem specyfikacje moich środowisk testowych, ponieważ nie jestem pewien, czy gcc, x86-64 i 64-bitowe długości są wystarczające. To powiedziawszy, przynajmniej na x86, funkcje bezzwrotne działają częściej z gcc (i tcc).
Dennis
Tak, właśnie ponownie przeczytałem pytanie i zgadzam się, że zaakceptowanie argumentu jako doublepowinno być w porządku. Nie mówi nic o wymaganiu od funkcji akceptacji w formacie base2. I tak, różne wersje gcc mogą emitować inny kod, więc to też ważne. (Ciekawostka: bez -mpopcnt, gcc nie użyje popcntinsn i wyemituje sekwencję instrukcji w celu jego emulacji. Niektóre architektury w ogóle nie mają instrukcji popcnt, więc __builtin_popcountlzawsze musi korzystać z sekwencji insns)
Peter Cordes
Tak, wiele (większość?) __builtin_*Funkcji ma starsze wersje, aby uniknąć generowania nielegalnych instrukcji. -march=nativeużywa popcntqtylko, jeśli jest dostępny.
Dennis
6

C (gcc), 63 bajty

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

To rozwiązanie opiera się na odpowiedzi @ LeakyNun, ale ponieważ nie chce poprawić swojej własnej odpowiedzi, zamieszczam tutaj bardziej golfową wersję.

Wypróbuj online


źródło
2
Bardzo wątpię, aby ktokolwiek nie chciał poprawić swojej odpowiedzi.
Pan Xcoder,
1
@ Mr.Xcoder. Ok, zatrzymam to tutaj, dopóki nie zredaguje własnej odpowiedzi. Jeśli nie chce edytować, pozostanie tutaj. Poprawkę opublikowałem jako komentarz do jego odpowiedzi, a on ją odrzucił.
1
Myślę, że dane wejściowe muszą być liczbami całkowitymi, a nie rzeczywistymi.
ceilingcat
3
@ThePirateBay Nie widziałem twojego komentarza do mojej odpowiedzi i nadal go nie widzę.
Leaky Nun
9
Decyzja o zasugerowaniu ulepszeń lub opublikowaniu własnej odpowiedzi należy do Ciebie, ale 6 minut to zaledwie około godziny .
Dennis
5

C #, 81 70 68 bajtów

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

Zaoszczędź 11 bajtów dzięki @Leaky Nun.
Zaoszczędź 2 bajty dzięki @Neil.

Wypróbuj online! Używa System.BitConverter.DoubleToInt64Bitszamiast unsafekodu, ponieważ nie mogłem zmusić TIO do pracy z nim.

Pełna / sformatowana wersja:

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
źródło
for(;l!=0;l*=2)i nie będziesz potrzebować trójskładnika
Leaky Nun
@LeakyNun Dzięki, od wieków drapałem się po głowie.
TheLethalCoder
Można użyć s-=l>>31?
Neil
@Neil Nie wydaje się działać. Zakładam, że masz zamiar zastąpić s+=l<0?1:0?
TheLethalCoder
Mój błąd; ljest długi, więc potrzebuje s-=l>>63?
Neil
4

Python 2 , 69 bajtów

-12 bajtów, dzięki tylko @ ASCII

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

Wypróbuj online!

Dead Possum
źródło
1
71 bajtów
tylko ASCII,
1
Gra w golfa swoje podejście, 76 bajtów , ja polecam ASCII-Only podejście choć
Pan Xcoder
@ Mr.Xcoder !nie jest potrzebny, ponieważ kolejność bajtów nie ma tutaj znaczenia
tylko ASCII
1
69 bajtów
tylko ASCII,
@ Tylko ASCII Spakuj rozpakowane. Dzięki: D
Dead Possum,
4

JavaScript (ES6), 81 80 77 bajtów

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

Edycja: Zapisano 1 bajt dzięki @Arnauld. Zaoszczędź 3 bajty dzięki @DocMax.

Neil
źródło
Czy możesz zrobić g(i^i&-i,x++)dla -1 bajtów?
Arnauld
@Arnauld Zastanawiałem się, czy nie było trochę golfisty, dziękuję za znalezienie go!
Neil
1
-3 więcej, jeśli zastąpi new Float64Array([n])sięFloat64Array.of(n)
DocMax
4

Kod maszynowy x86-64, 12 bajtów na int64_twejście

6 bajtów na doublewejście

Wymaga popcntrozszerzenia ISA ( CPUID.01H:ECX.POPCNT [Bit 23] = 1).

(Lub 13 bajtów, jeśli modyfikacja argumentu w miejscu wymaga zapisania wszystkich 64-bitów, zamiast pozostawiania śmieci w górnej 32. Myślę, że uzasadnione jest twierdzenie, że osoba dzwoniąca i tak prawdopodobnie chce załadować tylko niski 32b, a x86 zero - niejawnie rozszerza się z 32 na 64 przy każdej 32-bitowej operacji. Mimo to powstrzymuje dzwoniącego przed zrobieniem add rbx, [rdi]czegoś.)

Instrukcje x87 są krótsze niż bardziej oczywiste SSE2 cvtsi2sd/ movq(używane w odpowiedzi @ ceilingcat ), a [reg]tryb adresowania ma taki sam rozmiar jak reg: tylko bajt mod / rm.

Sztuczka polegała na znalezieniu sposobu na przekazanie wartości do pamięci, bez potrzeby zbyt wielu bajtów dla trybów adresowania. (np. przekazywanie stosu nie jest takie świetne.) Na szczęście reguły zezwalają na odczytywanie / zapisywanie argumentów lub oddzielne argumenty wyjściowe , więc mogę po prostu poprosić osobę wywołującą, aby przekazała mi wskaźnik do pamięci, którą wolno mi pisać.

Można wywołać z C z podpisem: void popc_double(int64_t *in_out); Tylko niskie 32b wyniku jest prawidłowe, co może być dziwne dla C, ale naturalne dla asm. (Naprawienie tego wymaga prefiksu REX w sklepie końcowym ( mov [rdi], rax), a więc jeszcze jednego bajtu.) W systemie Windows zmień rdina rdx, ponieważ Windows nie używa ABI x86-64 System V.

Lista NASM. Łącze TIO ma kod źródłowy bez demontażu.

  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

Wypróbuj online! Obejmuje_startprogram testowy, który przekazuje mu wartość i kończy działanie ze kodem zakończenia status = wartość zwracana popcnt. (Otwórz kartę „debugowanie”, aby ją zobaczyć.)

Przekazywanie oddzielnych wskaźników wejścia / wyjścia również by działało (rdi i rsi w x86-64 SystemV ABI), ale wtedy nie możemy racjonalnie zniszczyć 64-bitowego wejścia lub tak łatwo uzasadnić potrzebę 64-bitowego bufora wyjściowego, pisząc tylko niski 32b.

Jeśli chcemy argumentować, że możemy wziąć wskaźnik do wejściowej liczby całkowitej i zniszczyć go, zwracając dane wyjściowe do rax, po prostu pomiń mov [rdi], eaxod popcnt_double_outarg, zmniejszając go do 10 bajtów.


Alternatywa bez głupich sztuczek związanych z konwencją wywoływania, 14 bajtów

użyj stosu jako miejsca na zarysowania, pushaby się tam dostać. Użyj push/, popaby skopiować rejestry w 2 bajtach zamiast 3 dla mov rdi, rsp. ( [rsp]zawsze potrzebuje bajtu SIB, więc warto wydać 2 bajty, aby skopiować rspprzed trzema instrukcjami, które go używają).

Zadzwoń z C z tym podpisem: 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.

Akceptowanie danych wejściowych w doubleformacie

Pytanie tylko mówi, że jest liczbą całkowitą w pewnym zakresie, a nie, że musi być w reprezentacji binarnej liczby całkowitej base2. Akceptacja doubledanych wejściowych oznacza, że ​​nie ma już sensu używać x87. (Chyba że użyjesz niestandardowej konwencji wywoływania, w której doubles są przekazywane do rejestrów x87. Następnie zapisz w czerwonej strefie poniżej stosu i stamtąd popcnt.)

11 bajtów:

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

Ale możemy użyć tej samej sztuczki pass-by-reference jak poprzednio, aby stworzyć wersję 6-bajtową: int pcd(const double&d);

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

6 bajtów .

Peter Cordes
źródło
4

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

Zaoszczędzono 1 bajt dzięki hobbs

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

Wypróbuj online!

Xcali
źródło
Możesz zaoszczędzić 1 bajt, tworząc djedno słowo ( pack d,$_zamiast pack"d",$_)
hobbs
3

MATLAB, 36 bajtów

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

Wykorzystując fakt, że de2bijest nie tylko krótszy niżdec2bin , ale także daje wynik w postaci zer i jedynek zamiast ASCII 48, 49.

Sanchises
źródło
3

Java (64, 61, 41 bajtów)

Całkowicie prosty w użyciu standardowej biblioteki (Java SE 5+):

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

Wkład Kevina Cruijssena (Java SE 5+):

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

Wkład Kevina Cruijssena (Java SE 8+, funkcja lambda):

n->n.bitCount(Double.doubleToLongBits(n))
Nayuki
źródło
Ładnie wykonane! :-)
Leaky Nun
1
Dobra odpowiedź, +1 ode mnie. Możesz zagrać w golfa trzy bajty, biorąc parametr jako Long ni używaj n.bitCount(...)zamiast Long.bitCount(...). Ponadto, jeśli używasz Java 8+, możesz grać w golfa do n->n.bitCount(Double.doubleToLongBits(n))( 41 bajtów )
Kevin Cruijssen
2

Żeby wypróbować inne, bezpieczniejsze niż TheLethalCoder podejście, wpadłem na to (szkoda, że ​​C # ma tak długie nazwy metod):

C # (.NET Core) , 76 + 13 bajtów

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

Wypróbuj online!

Liczba bajtów obejmuje 13 bajtów using System;. Najpierw muszę przekonwertować doubleplik na taki, longktóry ma taką samą reprezentację binarną, a następnie mogę przekonwertować go na plik binarny string, a następnie liczę 1s, dzieląc ciąg i licząc podciągi minus 1.

Charlie
źródło
Dobra alternatywa, ale musisz uwzględnić usingw swojej liczbie bajtów.
TheLethalCoder
Używać LINQ do 95 bajtów tylko kilka: namespace System.Linq;{d=>Convert.ToString(BitConverter.DoubleToInt64Bits(d),2).Count(c=>c>48)}. Chociaż go nie testowałem, powinno działać.
TheLethalCoder
@TheLethalCoder to działa, ale starałem się unikać Linq, więc nie musiałem dodawać drugiej usingdyrektywy.
Charlie,
1
Kiedy dodasz drugi, wtedy namespacesię przyda. Ale tak, w tym przypadku unikanie Linq było nieco tańsze. Chciałem tylko skomentować to podejście na wypadek, gdybyś miał jakieś pomysły, jak je skrócić, aby zaoszczędzić bajty.
TheLethalCoder
@TheLethalCoder, Sum(c=>c&1)jest krótszy. LubSum()-768
Peter Taylor
1

dc, 79 bajtów

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

Wyjście pozostawia się na górze stosu.
Wyjaśnię później.

Wypróbuj online!

Zauważ, że liczby ujemne są poprzedzone _, a nie -.

poi830
źródło
1

C, 67 bajtów

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

kod kontrolny i wyniki

#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
źródło