754'den Hamming'e git


29

(522 52 ) ila (2 52 ) aralığında bir tamsayı girişi olarak size verilecektir . Gibi iyi bilinen , bu aralıkta tam sayılar tam olarak çift kesinlikli kayar nokta değerleri olarak ifade edilebilir.k-45035996273704964503599627370496

Bu durumda büyük çıkış Hamming ağırlığı kodlama bölgesinin (olanların sayısı) kolarak binary64 biçimi . Bu, işaret için 1 bit, üs için 11 bit (bir kayma ile kodlanmış) ve mantis için 52 kullanır; Ayrıntılar için yukarıdaki linke bakınız.

Bir de , örneğin , sayı 22olarak temsil edilir

0 10000000011 0110000000000000000000000000000000000000000000000000

Olduğundan 5olanlar, çıkış olduğunu 5.

Endianness'in sonucu etkilemediğine dikkat edin, bu sayede, çıkışı hesaplamak için makinenizin gerçek çift hassasiyetli değerlerin iç gösterimini güvenle kullanabilirsiniz.

Ek kurallar

Test durumları

22                ->   5
714               ->   6
0                 ->   0
1                 ->  10
4503599627370496  ->   5
4503599627370495  ->  55
1024              ->   3
-1024             ->   4
-4096             ->   5
1000000000        ->  16
-12345678         ->  16

1
İşlevlerin, isterlerse girişlerini zaten kayan nokta binary64biçiminde kabul edebilmelerini mi düşünüyorsunuz? Bazı insanlar (kendim de dahil) soruyu, fonksiyonların girdileri C'ler gibi bir tamsayı olarak kabul etmesini gerektiriyor olarak yorumluyorlardı long. C de, tıpkı aradığınız zaman dilin sizin için dönüştüğünü iddia edebilirsiniz sqrt((int)foo). Ancak , her ikisi de 64 bit tam sayı girişleri kabul etmek zorunda olduğumuzu farz eden bazı x86 makine kodu asm cevapları ( codegolf.stackexchange.com/a/136360/30206 ve benimki gibi ) vardır. Bir binary64değeri kabul etmek 5 bayttan tasarruf sağlar.
Peter Cordes,

Öyleyse, sınırlı aralıklarla ilgili tüm bu şeyler, birisinin tür kurgusu yerine binary64 bit modeline dönüşümünü kesmek istemesi durumunda olabilir mi? Veya yazı tipi olmayan diller için? Hmm, ilginç bir zorluk bir binary64base2 tamsayılarının üs ve mantislerini eklemek olabilir . Yine de onları ayrı ayrı ele almanız gerekiyorsa, tüm puntolarda punto ve loop dışında bir şey yapmaya değer olabilir.
Peter Cordes,

2
@PeterCordes Evet, kayan nokta sayısı biçiminde giriş yapabilirsiniz. Sınırlı aralık, kayan nokta gösteriminin doğru olduğundan emin olmaktır
Luis Mendo 15

Tamam teşekkürler. Sanırım bir işlev alma seçeneğinden ayrılmak istediniz long, bu yüzden herhangi bir binary64 söyleyemezsiniz double, çünkü her iki katı da tam sayı değildir. Ancak tüm tamsayı değerli doubledeğerler longsınırlarına kadar dönüştürülebilir long. (İşaret ettiğiniz gibi, tersi doğru değildir. doubleVarsayılan yuvarlama modunu varsayarak en yakın temsil edilebilir duruma gelirsiniz ). Her neyse, bu soruyu oluşturmanın tamamen geçerli bir yoluydu; Sadece dikkatlice okumadım>. <
Peter Cordes

"Endianness'ın sonucu etkilemediğine dikkat edin, bu nedenle çıktıyı hesaplamak için makinenizin gerçek çift hassasiyetli değerlerin iç gösterimini güvenle kullanabilirsiniz." Makineniz IEEE kayan nokta formatını kullanmıyorsa ...
Jerry Jeremiah

Yanıtlar:


8

MATL , 5 bayt

3Z%Bz

Çevrimiçi deneyin!

MATLAB cevabımın tam çevirisi. Girdi ve çıkışın örtük olduğuna dikkat edin. Luis Mendo sayesinde -2 bayt.

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

33

x86_64 makine dili (Linux), 16 bayt

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

64 bitlik bir tamsayı parametresini RDIkabul eder, içinde kayan nokta değerine dönüştürür XMM0, bu bitleri geri saklar RAXve ardından hamyanın ağırlığını hesaplayarak RAXsonucu RAXarayana geri döndürür .

POPCNTIntel Nehalem, AMD Barcelona ve daha sonra microarchitectures olan talimatı destekleyen bir işlemci gerektirir .

İçin çevrimiçi deneyin! , aşağıdaki C programını derleyin ve çalıştırın:

#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));
}

2
+1, iş için doğru araç! Bu, x86'nın yasal olarak golf dilleriyle rekabet edebileceği veya Jelly'i yenebileceği tek zaman olabilir. :)
DJMcMayhem

2
Ew, AT&T sözdizimi? objdump -drwC -MintelIntel sözdizimini sökmek için kullanabilirsiniz . Kayıt defterinde saklamak / yeniden yüklemek için kullanabileceğiniz bir işaretçi varsa, movaps [rsi], xmm0/ ile baytları kaydedebilirsiniz popcnt rax, [rsi]. (movaps yalnızca 3 bayttır, 2 movq değerinden 2 kısadır.) Fakat bu burada işe yaramaz, çünkü [rsp-24]2 ekstra bayt alır (SIB'nin RSP'yi taban olarak kullanması, artı disp8). Ve bu fazladan bayta hem mağazada hem de yeniden yükleme işleminde ihtiyaç duyulur. Pekala, bir tasarruf gördüm sanmıştım, ama hayır: /
Peter Cordes

Ben özel bir çağrı kuralı ile 4 bayt kaydedildi . Veya yine de x87 komutlarını kullanarak, aynı çağrı kuralına sahip 2 byte'ı kaydedin.
Peter Cordes

1
@DJMcMayhem: Belki de tek zaman değil. Extreme Fibonacci mücadelesinde golf dili cevapları hala yok (ilk 1000 rakamı Fib (1 milyar) yazdır ve x86 makine kodu yanıtımı (hızlı 105 bayt veya 1 dakika yerine 5 dakika çalışan 101 bayt) diğer cevapların bazılarından çok daha büyük değildir ve hepsi yerleşik olarak genişletilmiş hassasiyete sahip tamsayıları olan dillerdedir.
Peter Cordes

2
Ya da daha basit bir meydan okuma (ve bir performans gereksinimi olmadan), bir tam sayı dizisini harmanlayan chroma key . Makine kod cevabım pyth cevabının yarısı kadar.
Peter Cordes

11

C (gcc) , 82 68 bayt

Neil sayesinde 9 byte.

kötü kayan nokta bit seviyesi hack

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

Çevrimiçi deneyin!


İlk olacağını biliyordum, dili beklemiyordum :-D
Luis Mendo

@LuisMendo Ben sadece bu dilde uygun olacağını düşündüm ... Bunu yapabilen diğer dilleri bilmiyorum
Leaky Nun

2
Diğer yolu değiştirerek 9 bayt kazanın: ... ;long l=... ;l*=2;)s+=l<0;...
Neil

1
Bu elbette 64 bitlik bir C uygulaması gerektiriyor long. X86-64 Linux'ta çalışır, ancak Windows'ta başarısız olur. "64-bit ile gcc" demeyi öneririm long, çünkü gcc çoğu farklı ABI'ye sahip birçok platformda çalışıyor.
Peter Cordes

1
@ Peter adlı kullanıcının yorumu bir düzenleme içine "LP64" ekledim. Ayrıca diğer metni de daha mantıklı bir sıraya göre düşündüm. Sanırım bu değişikliği beğenmediniz ve geri aldınız, ancak LP64, uzun ve işaretçilerin 64-bit değerleri olduğu ABI'yi (standartların da 64-bit veya LLP64 olduğu ILP64 ile karşılaştırıldığında) tanımlayan standart bir terimdir. Windows'ta kullanıldığı gibi, yalnızca uzun ve işaretçilerin 64-bit ve uzunluğunun hala 32-bit olduğu). Belki de ilgili Wikipedia makalesine daha fazla açıklama veya satır içi bağlantı eklemeliydim.
Cody Gray,

8

Python 3 , 72 71 bayt

Lynn'e 1 bayt teşekkürler.

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

Çevrimiçi deneyin!

açıklama

Binary64 formatı üç bileşenden oluşur:

  • ilk bit işaret bitidir, yani 1sayı negatifse
  • sonraki 11 bit, üsteli 1023 eklenmiş olarak depolar.
  • sonraki 52 bit, anlam ya da mantisayı saklar.

n and(…)-(n>0)bayt daha kısa, hayır mı?
Lynn,

Ya da int-> float, ya da herhangi bir şekilde, bu konuda.
user2357112,

8

C (gcc) , 47 bayt

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

Bu taşınabilir değil; derleyici bayrakları olmadan Linux çalıştıran x86_64'te gcc 7.1.1 ile test edildi.

Çevrimiçi deneyin!


1
Giriş bir tamsayı olmalıdır. Ya da zımni dönüşüm ile arayan kolu olduğunu bildirmek için ok longiçin doubleçağrı yerinde?
Peter Cordes

1
Ayrıca, derleyici davranışının bir tesadüftü güvenerek bırakmak gerçekleşmesi nhalinde raxun-optimize kod oldukça sevimsiz ile. Etkinleştirirseniz kırılır -O3, bu nedenle genel olarak sadece gcc değildir long, optimizasyon devre dışı bırakılmış olarak 64 bitlik x86-64'teki gcc'dir . Tüm bu gereklilikleri cevabınıza eklerseniz, affederim. 64 bitlik gcc destekli platformlar olduğunu kabul ediyorum, longancak popcountlsonuçta geri dönüş değer kayıtlarından başka bir kayıtta kalıyor.
Peter Cordes

1
Matematiksel anlamda tamsayı aldım. Test ortamlarımın özelliklerini ekledim, çünkü gcc, x86-64 ve 64-bit uzunluğunun yeterli olduğundan emin değilim. Bununla birlikte, en azından x86'da, geri dönüşsüz işlevler gcc (ve tcc) işlevinden daha sık çalışır.
Dennis,

Evet, soruyu yeniden okuyordum ve argümanı bir kabul olarak kabul etmenin iyi olacağını kabul ediyorum double. İşlevin base2 biçiminde kabul etmesini istemekle ilgili hiçbir şey söylemez. Ve evet, farklı gcc sürümleri farklı kodlar çıkarabilirdi, bu da önemli. (Eğlenceli gerçek: -mpopcntgcc olmadan popcntinsn'i kullanmaz ve öykünmek için bir talimatlar dizisi yayar. Bazı mimarilerin popcnt komutları yoktur, bu yüzden __builtin_popcountldaima bir miktar insn kullanmak zorundadırlar.)
Peter Cordes

Evet, çoğu (çoğu?) __builtin_*İşlev, yasadışı talimatlar oluşturmamak için eski sürümlere sahiptir. sadece mevcutsa -march=nativekullanır popcntq.
Dennis,


6

C (gcc), 63 bayt

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

Bu çözüm @ LeakyNun'un cevabına dayanıyor, ancak kendi cevabını geliştirmek istemediği için burada daha fazla golf oyunu yayınlıyorum.

Çevrimiçi deneyin


2
Çok kimse şüphe etmez istiyor geliştirmek için onların cevabını.
Bay Xcoder,

1
@ Mr.Xcoder. Tamam, bunu kendi cevabını düzenleyene kadar burada tutacağım. Düzenlemek istemiyorsa, bu burada kalacak. Bu gelişmeyi cevabına yorum olarak gönderdim ve reddetti.

1
Bence girdi tamsayı tipinde olmalı ve gerçek değil.
ceilingcat

3
@ThePirateBay Cevabımla ilgili yorumunuzu görmedim ve hala şu anda göremiyorum.
Sızdıran Rahibe

9
Gelişmeler önerme veya kendi cevabınızı gönderme kararı size aittir, ancak 6 dakika neredeyse bir saat değildir .
Dennis,

5

C #, 81 70 68 bayt

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

@Leaky Nun sayesinde 11 bayt kazanın.
@Neil sayesinde 2 bayt kaydedildi.

Çevrimiçi deneyin! TIO'nun çalışmasını sağlayamadığım System.BitConverter.DoubleToInt64Bitsiçin unsafekod yerine kullanır .

Tam / Biçimli Sürüm:

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();
        }
    }
}

for(;l!=0;l*=2)ve
üçlüye

@ LeakyNun Teşekkürler ben başımı tırmalamak için uzun zamandır.
TheLethalCoder

Eğer kullanabilir miyim s-=l>>31?
Neil,

@Neil İşe görünmüyor. Değişim demek istediğinizi varsayıyorum s+=l<0?1:0?
TheLethalCoder

Benim hatam; luzun, bu yüzden ihtiyacı var s-=l>>63?
Neil,


4

JavaScript (ES6), 81 80 77 bayt

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

Düzenleme: @Arnauld sayesinde 1 bayt kaydedildi. @DocMax sayesinde 3 byte kurtarıldı.


g(i^i&-i,x++)-1 bayt için yapabilir misiniz ?
Arnauld,

@Ardı mı buldum bir golfier bit twiddle olup olmadığını merak ettim, onu bulmak için teşekkürler!
Neil,

1
-3 new Float64Array([n])ile değiştirirsenizFloat64Array.of(n)
DocMax

4

x86-64 makine kodu, int64_tgiriş için 12 bayt

doubleGiriş için 6 bayt

popcntISA uzantısını ( CPUID.01H:ECX.POPCNT [Bit 23] = 1) gerektirir .

(Veya argümanı yerinde değiştirmek gerekirse, üst biti (32) çöp bırakmak yerine 64 bitin tümünü yazmayı gerektirir. Arayanın muhtemelen sadece düşük 32b ve x86 sıfırı yüklemek isteyeceğini iddia etmenin makul olduğunu düşünüyorum. - Her 32 bitlik işlemle örtük olarak 32'den 64'e kadar uzanır. Yine de, arayanı yapmasını add rbx, [rdi]veya bir şey yapmasını engeller .)

x87 komutları, daha belirgin olan SSE2 cvtsi2sd/ ' den daha kısadır movq( @ ceilingcat'in cevabında kullanılır ) ve [reg]adresleme modu a ile aynı boyuttadır reg: sadece bir mod / rm bayt.

İşin püf noktası, adresleme modları için çok fazla bayta ihtiyaç duymadan, değerin bellekte geçirilmesini sağlayacak bir yol bulmaktı. (örneğin yığına geçmek o kadar da iyi değil.) Neyse ki, kurallar okuma / yazma argümanlarına veya ayrı çıkış argümanlarına izin veriyor , bu yüzden arayanın yazmama izin verdiği bir işaretçi göndermesini sağlayabilirim.

İmzayla C'den aranabilir: void popc_double(int64_t *in_out); Sonucun yalnızca düşük 32b'si geçerlidir, bu C için tuhaf olabilir ama asm için doğaldır. (Bu sabitleme nihai deposunda (bir REX öneki gerektirir mov [rdi], raxWindows değişiminde), bu yüzden bir daha bayt.) rdiİçin rdx, Windows X86-64 Sistem V ABI kullanmaz çünkü.

NASM listesi. TIO bağlantısının demontaj olmadan kaynak kodu vardır.

  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

Çevrimiçi deneyin! _startBir değeri ileten ve exit status = popcnt return değeri ile çıkan birtest programıiçerir. (Görmek için "hata ayıklama" sekmesini açın.)

Ayrı giriş / çıkış işaretçileri geçmek de işe yarayabilir (x86-64 SystemV ABI'deki rdi ve rsi), ancak sonra 64-bit girişi makul bir şekilde yok edemeyiz ya da sadece 64-bit çıkış arabelleğine ihtiyaç duyarken kolayca gerekçelendirebiliriz. düşük 32b.

Eğer giriş göstergesine bir gösterici alabileceğimizi ve onu çıktısını alırken imha edebileceğimizi iddia etmek istiyorsak rax, sonra mov [rdi], eaxgelenleri atlayarak popcnt_double_outarg10 bayta indirgeyelim.


Aptalca çağrı-kongre hileleri, 14 bayt olmadan alternatif

yığını pushoraya sıfırdan boşluk olarak kullanın . Kayıtları için 3 yerine 2 bayt olarak kopyalamak için push/ kullanın . ( her zaman bir SIB baytına ihtiyaç duyar, bu yüzden onu kullanan üç talimattan önce kopyalamak için 2 bayt harcamakta fayda var.)popmov rdi, rsp[rsp]rsp

Bu imzayla C'den arayın: 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.

Giriş doublebiçimini kabul etme

Soru sadece belli bir aralıktaki bir tamsayı olduğunu söylüyor, bunun bir base2 ikili tamsayı gösterimi içinde olması gerekmiyor. doubleGirdiyi kabul etmek, artık x87 kullanmanın bir anlamı olmadığı anlamına gelir. ( doubleX87 sicillerinde s iletilen özel bir çağrı kuralı kullanmazsanız . Sonra yığının altındaki kırmızı bölgeye saklayın ve oradan açılır.)

11 bayt:

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

Ancak, 6 baytlık bir sürüm oluşturmak için önceki gibi aynı referans numarası kullanabilirsiniz: int pcd(const double&d);

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

6 bayt .


4

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

Hobbs sayesinde 1 bayt kaydedildi

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

Çevrimiçi deneyin!


Sen yaparak 1 byte kaydedebilirsiniz dbir bareword ( pack d,$_yerine pack"d",$_)
hobbs

3

MATLAB, 36 bayt

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

Gerçeğini kullanarak de2bidaha sadece kısadır dec2bin, aynı zamanda birler ve sıfırlar yerine ASCII 48, 49 bir sonuç sağlar.


3

Java (64, 61, 41 bayt)

Standart kütüphaneyi kullanarak tamamen basittir (Java SE 5+):

int f (uzun n) {dönüş Uzun. bitCount (Double. doubleToLongBits (n));}

Kevin Cruijssen'in Katkısı (Java SE 5+):

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

Kevin Cruijssen'in katkısı (Java SE 8+, lambda işlevi):

n->n.bitCount(Double.doubleToLongBits(n))

Güzel bitti! :-)
Leaky Nun

1
Güzel cevap, benden +1. Sen golf olarak parametreyi alarak üç bayt can Long nve kullanım n.bitCount(...)yerine Long.bitCount(...). Ek olarak, eğer Java 8+ kullanıyorsanız, n->n.bitCount(Double.doubleToLongBits(n))( 41 byte )
oynayabilirsiniz

2

Sadece farklı, daha TheLethalCoder'ın yaklaşımından daha güvenli bir şekilde denemek için şunu anladım :

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

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

Çevrimiçi deneyin!

Bayt sayısı için 13 bayt içerir using System;. Önce dönüştürmek için gereken doublebir karşı longaynı ikili gösterimini sahip olduğunu, o zaman bir ikili dönüştürebilirsiniz string, sonra saymak 1bölünme ile sadece dize ve alt dizeleri eksi 1 sayma s.


Güzel bir alternatif ancak usingbayt sayınıza dahil etmeniz gerekir .
TheLethalCoder

95 için kullanın Linq sadece birkaç fazla bayt: namespace System.Linq;{d=>Convert.ToString(BitConverter.DoubleToInt64Bits(d),2).Count(c=>c>48)}. Test etmemiş olmama rağmen çalışması gerekiyor.
TheLethalCoder

@TheLethalCoder çalışır, ancak Linq'ten kaçınmaya çalıştım, böylece ikinci bir usingyönergeyi eklemek zorunda kalmadım .
Charlie,

1
İkinciyi eklediğinizde, işe yarayan o zaman namespace. Fakat evet, bu durumda Linq'ten kaçınmak biraz daha ucuzdu. Sadece baytları kurtarmak için nasıl kısaltılacağına dair herhangi bir fikriniz varsa, yaklaşımı ile ilgili yorum yapmak istedim.
TheLethalCoder

@TheLethalCoder, Sum(c=>c&1)daha kısa. VeyaSum()-768
Peter Taylor


1

dc, 79 bayt

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

Çıktı yığının üstüne bırakılmıştır.
Daha sonra bir açıklama ekleyeceğim.

Çevrimiçi deneyin!

Negatif sayılardan önce geldiğine _dikkat edin -.



1

C, 67 bayt

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

kontrol kodu ve sonuçları

#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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.