Float 754 ke Hamming

29

Anda akan diberikan sebagai input bilangan bulat kdalam rentang dari -4503599627370496(−2 52 ) hingga 4503599627370496(2 52 ). Seperti diketahui , bilangan bulat dalam kisaran ini dapat direpresentasikan tepat sebagai nilai floating-point presisi ganda.

Anda harus keluaran yang berat Hamming (jumlah orang) dari pengkodean kdalam format yang binary64 . Ini menggunakan 1 bit untuk tanda, 11 bit untuk eksponen (dikodekan dengan offset), dan 52 bit untuk mantissa; lihat tautan di atas untuk detailnya.

Sebagai contoh , angka 22direpresentasikan sebagai

0 10000000011 0110000000000000000000000000000000000000000000000000

Karena ada 5, outputnya adalah 5.

Perhatikan bahwa endianness tidak memengaruhi hasil, sehingga Anda dapat dengan aman menggunakan representasi internal aktual dari nilai presisi ganda untuk menghitung output.

Aturan tambahan

Uji kasus

22                ->   5
714               ->   6
0                 ->   0
1                 ->  10
4503599627370496  ->   5
4503599627370495  ->  55
1024              ->   3
-1024             ->   4
-4096             ->   5
1000000000        ->  16
-12345678         ->  16
Luis Mendo
sumber
1
Apakah Anda bermaksud bahwa fungsi dapat menerima input mereka sudah dalam binary64format floating-point jika mereka mau? Beberapa orang (termasuk saya sendiri, awalnya) yang menafsirkan pertanyaan sebagai membutuhkan yang berfungsi menerima masukan sebagai tipe integer seperti C long. Di C, Anda dapat berargumen bahwa bahasa akan dikonversi untuk Anda, sama seperti ketika Anda menelepon sqrt((int)foo). Tetapi ada beberapa jawaban kode mesin x86 asm (seperti codegolf.stackexchange.com/a/136360/30206 dan milik saya) yang sama-sama berasumsi kita harus menerima input integer 64-bit. Menerima binary64nilai akan menghemat 5 byte.
Peter Cordes
Jika demikian, maka semua hal tentang rentang terbatas itu untuk berjaga-jaga jika seseorang ingin meretas konversi ke pola bit binary64 sendiri alih-alih tipe-punning? Atau untuk bahasa tanpa hukuman jenis? Hmm, tantangan yang menarik mungkin menambahkan eksponen dan mantissa binary64sebagai bilangan bulat basis2. Jika Anda perlu menanganinya secara terpisah, mungkin ada baiknya melakukan sesuatu selain mengetik-pun dan mengulangi semua bit.
Peter Cordes
2
@PeterCordes Ya, Anda dapat memasukkan dalam bentuk angka floating-point. Jangkauan terbatas adalah untuk memastikan bahwa representasi floating-point akurat
Luis Mendo
Ok terima kasih. Saya kira Anda ingin meninggalkan opsi untuk menulis fungsi yang membutuhkan long, jadi Anda tidak bisa hanya mengatakan binary64 double, karena tidak semua ganda adalah bilangan bulat. Tetapi semua nilai integer doubledapat dikonversi ke longdan kembali, hingga batas long. (Seperti yang Anda tunjukkan, kebalikannya tidak benar. Anda mendapatkan representable terdekat double, dengan asumsi mode pembulatan default). Bagaimanapun, ini adalah cara yang benar-benar valid untuk mengatur pertanyaan; Saya hanya tidak membacanya dengan cermat>. <
Peter Cordes
"Perhatikan bahwa endianness tidak memengaruhi hasil, sehingga Anda dapat dengan aman menggunakan representasi internal aktual dari nilai presisi ganda untuk menghitung output." kecuali mesin Anda tidak menggunakan format floating point IEEE ...
Jerry Jeremiah

Jawaban:

8

MATL , 5 byte

3Z%Bz

Cobalah online!

Transliterasi yang tepat dari jawaban MATLAB saya. Perhatikan bahwa input dan output bersifat implisit. -2 byte terima kasih kepada 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
sumber
33

bahasa mesin x86_64 (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

Menerima parameter integer 64-bit tunggal dalam RDI, mengubahnya menjadi nilai floating-point XMM0, menyimpan bit-bit itu kembali RAX, dan kemudian menghitung berat hamming RAX, meninggalkan hasilnya RAXsehingga dapat dikembalikan ke pemanggil.

Membutuhkan prosesor yang mendukung POPCNTinstruksi, yang akan menjadi Intel Nehalem, AMD Barcelona, ​​dan kemudian mikroarsitektur.

Untuk Mencoba secara online! , kompilasi dan jalankan program C berikut:

#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));
}
plafon
sumber
2
+1, alat yang tepat untuk pekerjaan itu! Ini mungkin satu-satunya waktu x86 yang dapat bersaing secara sah dengan bahasa golf, atau mengalahkan Jelly. :)
DJMcMayhem
2
Ew, sintaks AT&T? Anda dapat menggunakannya objdump -drwC -Minteluntuk membongkar dalam sintaks Intel. Jika Anda memiliki pointer dalam register yang bisa Anda gunakan untuk menyimpan / memuat ulang, Anda bisa menyimpan byte dengan movaps [rsi], xmm0/ popcnt rax, [rsi]. (movaps hanya 3 byte, 2 lebih pendek dari movq.) Tapi itu tidak membantu di sini, karena [rsp-24]membutuhkan 2 byte tambahan (SIB menggunakan RSP sebagai basis, plus disp8). Dan byte tambahan itu diperlukan baik di store maupun reload. Oh well, saya pikir saya melihat tabungan, tetapi tidak: /
Peter Cordes
Saya menyimpan 4 byte dengan konvensi pemanggilan kustom . Atau masih menyimpan 2 byte dengan konvensi panggilan yang sama seperti ini, dengan menggunakan instruksi x87.
Peter Cordes
1
@DJMcMayhem: Mungkin bukan satu-satunya waktu. Masih belum ada jawaban bahasa-golf pada tantangan Fibonacci Ekstrim (cetak 1000 digit pertama Fib (1 miliar), dan jawaban kode mesin x86 saya (105 byte cepat, atau 101 byte yang berjalan dalam 5 menit alih-alih 1 menit) tidak jauh lebih besar dari beberapa jawaban lain, dan semuanya dalam bahasa dengan bilangan bulat presisi yang diperluas.
Peter Cordes
2
Atau tantangan yang lebih sederhana, (dan tanpa persyaratan kinerja), kunci chroma memadukan array bilangan bulat . Jawaban kode mesin saya adalah setengah panjang dari jawaban pyth.
Peter Cordes
11

C (gcc) , 82 68 byte

9 byte berkat Neil.

peretasan tingkat bit floating point jahat

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

Cobalah online!

Biarawati Bocor
sumber
Saya tahu Anda akan menjadi yang pertama, saya hanya tidak mengharapkan bahasa :-D
Luis Mendo
@LuisMendo Saya hanya berpikir bahwa akan lebih mudah dalam bahasa itu ... Saya tidak tahu bahasa lain yang bisa melakukan ini
Leaky Nun
2
Hemat 9 byte dengan menggeser ke arah lain: ... ;long l=... ;l*=2;)s+=l<0;...
Neil
1
Ini tentu saja membutuhkan implementasi C dengan 64-bit long. Ini bekerja pada x86-64 Linux, tetapi akan gagal pada Windows. Saya sarankan mengatakan "gcc dengan 64-bit long", karena gcc berjalan pada banyak platform, banyak dari mereka dengan ABI yang berbeda.
Peter Cordes
1
Komentar @ Peter adalah alasan saya menambahkan "LP64" dalam sebuah suntingan. Saya juga mengatur ulang teks lain dalam apa yang saya pikir merupakan urutan yang lebih logis. Saya kira Anda tidak menyukai perubahan itu dan mengembalikannya, tetapi LP64 adalah istilah standar yang menggambarkan ABI di mana long dan pointer adalah nilai 64-bit (dibandingkan dengan ILP64, di mana int juga 64-bit, atau LLP64, seperti yang digunakan pada Windows di mana hanya long dan pointer 64-bit dan long masih 32-bit). Mungkin saya harus menambahkan lebih banyak penjelasan, atau tautan sebaris ke artikel Wikipedia yang relevan.
Cody Grey
8

Python 3 , 72 71 byte

Terima kasih 1 byte untuk Lynn.

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

Cobalah online!

Penjelasan

Format binary64 terdiri dari tiga komponen:

  • bit pertama adalah bit tanda, yaitu 1jika angkanya negatif
  • 11 bit berikutnya menyimpan eksponen dengan 1023 ditambahkan
  • 52 bit selanjutnya menyimpan signifikasi, atau mantissa.
Biarawati Bocor
sumber
n and(…)-(n>0)Apakah byte lebih pendek, bukan?
Lynn
Atau int-> float, atau mengapung sama sekali, dalam hal ini.
user2357112 mendukung Monica
8

C (gcc) , 47 byte

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

Ini tidak portabel; itu diuji dengan gcc 7.1.1 pada x86_64 yang menjalankan Linux, tanpa flag compiler.

Cobalah online!

Dennis
sumber
1
Input harus berupa bilangan bulat. Atau apakah boleh membiarkan penelepon mengatasinya dengan konversi tersirat longke doubledi situs panggilan?
Peter Cordes
1
Juga, mengandalkan kebetulan perilaku compiler terjadi untuk meninggalkan ndi raxdengan un-kode dioptimalkan cukup cheesy. Itu rusak jika Anda mengaktifkan -O3, jadi itu bukan hanya gcc pada umumnya, itu gcc pada x86-64 dengan 64-bit longdengan optimasi dinonaktifkan. Jika Anda memasukkan semua persyaratan itu ke dalam jawaban Anda, saya akan menang. Saya akan berasumsi ada platform yang mendukung gcc yang memiliki 64-bit longtetapi itu meninggalkan popcountlhasil dalam register selain dari register nilai-kembali.
Peter Cordes
1
Saya mengambil bilangan bulat dalam arti matematika. Saya telah menambahkan spesifikasi lingkungan pengujian saya, karena saya tidak yakin bahwa panjang gcc, x86-64, dan 64-bit sudah cukup. Yang mengatakan, setidaknya pada x86, fungsi return-less bekerja dengan gcc (dan tcc) lebih sering daripada tidak.
Dennis
Ya, saya baru saja membaca ulang pertanyaannya, dan saya setuju bahwa menerima arg sebagai doublehal yang baik-baik saja. Itu tidak mengatakan apa-apa tentang memerlukan fungsi untuk menerimanya dalam format base2. Dan ya, berbagai versi gcc dapat memancarkan kode yang berbeda, jadi itu juga penting. (Fakta menyenangkan: tanpa -mpopcnt, gcc tidak akan menggunakan popcntinsn, dan akan memancarkan urutan instruksi untuk menirunya. Beberapa arsitektur tidak memiliki instruksi popcnt sama sekali, jadi __builtin_popcountlselalu harus menggunakan beberapa urutan insns)
Peter Cordes
Ya, banyak __builtin_*fungsi (sebagian besar?) Memiliki versi lama untuk menghindari pembuatan instruksi ilegal. hanya -march=nativedigunakan popcntqjika tersedia.
Dennis
6

C (gcc), 63 byte

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

Solusi ini didasarkan pada jawaban @ LeakyNun, tetapi karena dia tidak ingin meningkatkan jawabannya sendiri, saya memposting di sini versi yang lebih golf.

Cobalah online


sumber
2
Saya sangat meragukan ada orang yang tidak ingin meningkatkan jawaban mereka.
Tn. Xcoder
1
@ Mr.Xcoder. Ok, saya akan menyimpan ini di sini sampai dia mengedit jawabannya sendiri. Jika dia tidak ingin mengedit, ini akan tetap di sini. Saya memposting peningkatan ini sebagai komentar atas jawabannya dan dia menolaknya.
1
Saya pikir input perlu tipe integer dan bukan yang asli.
ceilingcat
3
@ThePirateBay Saya tidak melihat komentar Anda tentang jawaban saya dan saya masih belum melihatnya sekarang.
Leaky Nun
9
Keputusan untuk menyarankan peningkatan atau memposting jawaban Anda sendiri adalah milik Anda, tetapi 6 menit bukanlah sekitar satu jam .
Dennis
5

C #, 81 70 68 byte

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

Simpan 11 byte berkat @Leaky Nun.
Disimpan 2 byte berkat @Neil.

Cobalah online! Menggunakan System.BitConverter.DoubleToInt64Bitsalih-alih unsafekode karena saya tidak bisa membuat TIO bekerja dengannya.

Versi Lengkap / Diformat:

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
sumber
for(;l!=0;l*=2)dan Anda tidak akan memerlukan ternary
Leaky Nun
@ LeakyNun Terima kasih, aku sudah menggaruk-garuk kepalaku sejak lama.
TheLethalCoder
Dapatkah Anda menggunakan s-=l>>31?
Neil
@Neil Tampaknya tidak berfungsi. Saya menganggap Anda bermaksud untuk mengganti s+=l<0?1:0?
TheLethalCoder
Salahku; lpanjang, jadi itu perlu s-=l>>63?
Neil
4

Python 2 , 69 byte

-12 byte, terima kasih hanya untuk @ ASCII

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

Cobalah online!

Possum Mati
sumber
1
71 byte
ASCII
1
Bermain
@ Mr.Xcoder !tidak diperlukan karena urutan byte tidak masalah di sini
ASCII-satunya
1
69 byte
ASCII
@ ASCII-only. Kemas yang dibongkar. Terima kasih: 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

Sunting: Disimpan 1 byte berkat @Arnauld. Disimpan 3 byte berkat @DocMax.

Neil
sumber
Bisakah Anda melakukannya g(i^i&-i,x++)untuk -1 byte?
Arnauld
@Arnauld, saya memang bertanya-tanya apakah ada permainan golf yang lebih menarik, terima kasih telah menemukannya!
Neil
1
-3 lagi jika Anda ganti new Float64Array([n])denganFloat64Array.of(n)
DocMax
4

kode mesin x86-64, 12 byte untuk int64_tinput

6 byte untuk doubleinput

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

(Atau 13 byte jika memodifikasi arg di tempat membutuhkan penulisan semua 64-bit, daripada meninggalkan sampah di atas 32. Saya pikir masuk akal untuk berargumen bahwa penelepon mungkin hanya ingin memuat 32b yang rendah, dan x86 nol -memperluas dari 32 ke 64 secara implisit dengan setiap operasi 32-bit. Namun, itu menghentikan penelepon untuk melakukan add rbx, [rdi]atau sesuatu.)

Instruksi x87 lebih pendek daripada SSE2 cvtsi2sd/ yang lebih jelas movq(digunakan dalam jawaban @ ceilingcat ), dan [reg]mode pengalamatan berukuran sama dengan reg: hanya mod / byte byte.

Kuncinya adalah menemukan cara agar nilai yang dilewatkan dalam memori, tanpa perlu terlalu banyak byte untuk menangani mode. (mis. meneruskan pada stack tidak terlalu bagus.) Untungnya, aturan memperbolehkan read / write args, atau memisahkan output args , jadi saya bisa membuat penelepon memberikan saya sebuah pointer ke memori yang saya boleh tulis.

Dipanggil dari C dengan tanda tangan: void popc_double(int64_t *in_out); Hanya 32b rendah dari hasilnya yang valid, yang mungkin aneh untuk C tetapi wajar untuk asm. (Memperbaiki ini membutuhkan awalan REX di toko akhir ( mov [rdi], rax), jadi satu byte lagi.) Di Windows, ubah rdike rdx, karena Windows tidak menggunakan Sistem V ABI x86-64.

Daftar NASM. TIO link memiliki kode sumber tanpa pembongkaran.

  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

Cobalah online! Termasuk_startprogram pengujian yang memberikan nilai dan keluar dengan status keluar = nilai balik popcnt. (Buka tab "debug" untuk melihatnya.)

Melewati pointer input / output yang terpisah juga akan berfungsi (rdi dan rsi di System86 ABI x86-64), tetapi kemudian kita tidak dapat menghancurkan input 64-bit atau dengan mudah membenarkan memerlukan buffer output 64-bit sementara hanya menulis rendah 32b.

Jika kita ingin berdebat bahwa kita dapat mengambil pointer ke integer input dan menghancurkannya, sambil mengembalikan output rax, maka cukup hilangkan mov [rdi], eaxdari popcnt_double_outarg, turunkan menjadi 10 byte.


Alternatif tanpa trik konvensi panggilan yang konyol, 14 byte

gunakan tumpukan sebagai ruang awal, dengan pushuntuk mendapatkannya di sana. Gunakan push/ popuntuk menyalin register dalam 2 byte, bukan 3 untuk mov rdi, rsp. ( [rsp]selalu membutuhkan SIB byte, jadi perlu menghabiskan 2 byte untuk menyalin rspsebelum tiga instruksi yang menggunakannya.)

Panggilan dari C dengan tanda tangan ini: 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.

Menerima input dalam doubleformat

Pertanyaannya hanya mengatakan itu adalah bilangan bulat dalam rentang tertentu, bukan karena itu harus dalam representasi bilangan bulat biner base2. Menerima doubleinput berarti tidak ada gunanya menggunakan x87 lagi. (Kecuali jika Anda menggunakan konvensi panggilan kustom doubledi mana s dilewatkan dalam register x87. Kemudian simpan ke zona merah di bawah tumpukan, dan muncul dari sana.)

11 byte:

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

Tetapi kita dapat menggunakan trik pass-by-reference yang sama seperti sebelumnya untuk membuat versi 6-byte: int pcd(const double&d);

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

6 byte .

Peter Cordes
sumber
4

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

Disimpan 1 byte berkat hobbs

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

Cobalah online!

Xcali
sumber
Anda dapat menghemat 1 byte dengan membuat dkata kunci ( pack d,$_bukan pack"d",$_)
hobbs
3

MATLAB, 36 byte

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

Menggunakan fakta yang de2bitidak hanya lebih pendek dari dec2bin, tetapi juga memberikan hasil dalam satu dan nol daripada ASCII 48, 49.

Sanchises
sumber
3

Java (64, 61, 41 byte)

Benar-benar mudah menggunakan perpustakaan standar (Java SE 5+):

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

Kontribusi oleh Kevin Cruijssen (Java SE 5+):

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

Kontribusi oleh Kevin Cruijssen (Java SE 8+, fungsi lambda):

n->n.bitCount(Double.doubleToLongBits(n))
Nayuki
sumber
Bagus sekali! :-)
Leaky Nun
1
Jawaban yang bagus, +1 dari saya. Anda bisa bermain golf tiga byte dengan menggunakan parameter sebagai Long ndan menggunakan n.bitCount(...)sebagai gantinya Long.bitCount(...). Selain itu, jika Anda menggunakan Java 8+, Anda dapat memasukkannya ke n->n.bitCount(Double.doubleToLongBits(n))( 41 byte )
Kevin Cruijssen
2

Hanya untuk mencoba yang berbeda, lebih aman dari- daripada TheLethalCoder , saya datang dengan ini (Sayang sekali C # memiliki nama metode yang panjang):

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

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

Cobalah online!

Jumlah byte termasuk 13 byte untuk using System;. Pertama, saya perlu mengonversikan doubleke a longyang memiliki representasi biner yang sama, lalu saya dapat mengonversinya menjadi biner string, dan kemudian saya menghitung 1s hanya dengan memisahkan string dan menghitung substring minus 1.

Charlie
sumber
Alternatif yang bagus tetapi Anda harus memasukkan usingke dalam byte byte Anda.
TheLethalCoder
Gunakan Linq untuk 95 byte hanya beberapa: namespace System.Linq;{d=>Convert.ToString(BitConverter.DoubleToInt64Bits(d),2).Count(c=>c>48)}. Meskipun saya belum mengujinya, itu seharusnya berhasil.
TheLethalCoder
@TheLethalCoder berfungsi, tapi saya mencoba menghindari Linq jadi saya tidak perlu menambahkan usingarahan kedua .
Charlie
1
Ketika Anda menambahkan yang kedua saat itulah namespaceberguna. Tapi ya dalam hal ini menghindari Linq sedikit lebih murah. Hanya ingin berkomentar dengan pendekatan itu jika Anda punya ide tentang cara mempersingkatnya untuk menghemat byte.
TheLethalCoder
@TheLethalCoder, Sum(c=>c&1)lebih pendek. AtauSum()-768
Peter Taylor
1

Jelly , 19 byte

AB©L+⁽¡ßB;®ċ1_>0$a@

Cobalah online!

Biarawati Bocor
sumber
1

dc, 79 byte

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

Output dibiarkan di atas tumpukan.
Saya akan menambahkan penjelasan nanti.

Cobalah online!

Perhatikan bahwa angka negatif didahului oleh _, bukan -.

poi830
sumber
1

C, 67 byte

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

kode kontrol dan hasil

#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
sumber