754 হ্যামিং থেকে ভাসা


29

আপনি যত দেয়া হবে ইনপুট একটি পূর্ণসংখ্যা kথেকে সীমার মধ্যে -4503599627370496(-2 52 পর্যন্ত) 4503599627370496(2 52 )। যেমনটি সুপরিচিত , এই পরিসীমাতে পূর্ণসংখ্যাগুলি ডাবল-স্পষ্টতা ভাসমান-পয়েন্টের মান হিসাবে প্রতিনিধিত্ব করা যেতে পারে।

আপনি উচিত আউটপুট Hamming ওজন এর এনকোডিং (বেশী সংখ্যা) kমধ্যে binary64 বিন্যাস । এটি সাইনটির জন্য 1 বিট, এক্সপোনেন্টটির জন্য 11 বিট (অফসেট সহ এনকোডেড) এবং ম্যান্টিসার জন্য 52 টি ব্যবহার করে; বিস্তারিত জানার জন্য উপরের লিঙ্কটি দেখুন।

একটি উদাহরণ হিসাবে , সংখ্যা 22হিসাবে প্রতিনিধিত্ব করা হয়

0 10000000011 0110000000000000000000000000000000000000000000000000

যেহেতু সেখানে আছে 5, আউটপুট হয় 5

মনে রাখবেন যে পরিণতি ফলাফলকে প্রভাবিত করে না, তাই আপনি আউটপুট গণনা করতে আপনার মেশিনের ডাবল-স্পষ্টতা মানগুলির প্রকৃত অভ্যন্তরীণ উপস্থাপনাটি নিরাপদে ব্যবহার করতে পারেন।

অতিরিক্ত বিধি

পরীক্ষার মামলা

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

1
আপনি কি চান যে ফাংশনগুলি binary64যদি তারা চান তবে ইতিমধ্যে ভাসমান-পয়েন্ট ফর্ম্যাটে তাদের ইনপুটগুলি গ্রহণ করতে পারে ? কিছু মানুষ (নিজেকে প্রাথমিকভাবে সহ) আবশ্যক করার ফাংশন সি এর মত একটি পূর্ণসংখ্যা প্রকার ইনপুট গ্রহণ যেমন প্রশ্ন ব্যাখ্যা করা হয়েছে long। সি-তে আপনি যুক্তি দিতে পারেন যে ভাষাটি আপনার জন্য রূপান্তর করবে ঠিক যেমন আপনি কল করার সময় sqrt((int)foo)। তবে কিছু x86 মেশিন-কোড asm উত্তর রয়েছে (যেমন কোডগল্ফ.স্ট্যাকেক্সেক্সঞ্জ.com/a/136360/30206 এবং খনি) যা উভয়ই ধরে নিয়েছিল যে আমাদের 64-বিট পূর্ণসংখ্যার ইনপুট গ্রহণ করতে হবে। একটি binary64মান গ্রহণ করা 5 বাইট সংরক্ষণ করতে পারে।
পিটার কর্ডেস

যদি তা হয় তবে সীমাবদ্ধ-পরিসীমা সম্পর্কে সমস্ত স্টাফ কেবল সেই ক্ষেত্রে যদি কেউ টাইপ-পাঞ্জিংয়ের পরিবর্তে বাইনারি bit৪ বিট-প্যাটার্নে রূপান্তরটি হ্যাক করতে চায়? বা টাইপ-পাঞ্জাবিহীন ভাষার জন্য? হুম, একটি আকর্ষণীয় চ্যালেঞ্জ হতে পারে binary64বেস 2 পূর্ণসংখ্যার হিসাবে কোনওর যোগফল এবং ম্যান্টিসা যুক্ত করা । যদি আপনার যেকোন উপায়ে আলাদাভাবে পরিচালনা করতে হয় তবে এটি সমস্ত বিটগুলির মধ্যে টাইপ-পাং এবং লুপ ব্যতীত অন্য কিছু করা ভাল।
পিটার কর্ডেস

2
@ পিটারকর্ডস হ্যাঁ, আপনি আ ফ্লোটিং-পয়েন্ট নম্বর আকারে ইনপুট করতে পারেন। সীমিত পরিসীমাটি ভাসমান-পয়েন্ট উপস্থাপনাটি সঠিক কিনা তা নিশ্চিত করা হয়
লুইস মেন্ডো

ঠিক আছে ধন্যবাদ. আমি অনুমান করি যে আপনি একটি ফাংশন লেখার বিকল্পটি ছেড়ে যেতে চেয়েছিলেন যা একটি নেয় long, তাই আপনি কেবল কোনও বাইনারি 64 বলতে পারেন না double, কারণ সমস্ত ডাবলগুলি পূর্ণসংখ্যা হয় না। তবে সমস্ত পূর্ণসংখ্যার মানগুলি doubleএর longসীমাতে ফিরে এবং পিছনে রূপান্তর করা যায় long। (আপনি যেমন উল্লেখ করেছেন, বিপরীতটি সত্য নয় doubledefault আপনি ডিফল্ট রাউন্ডিং মোড ধরে ধরে নিকটতম উপস্থাপনযোগ্য পাবেন )। যাইহোক, এই প্রশ্নটি সেট আপ করার জন্য এটি একটি সম্পূর্ণ বৈধ উপায় ছিল; আমি এটা সাবধানে> পড়তেন না <।
পিটার Cordes

"মনে রাখবেন যে পরিণতি ফলাফলকে প্রভাবিত করে না, তাই আপনি আউটপুট গণনা করতে আপনার মেশিনের ডাবল-স্পষ্টতা মানগুলির প্রকৃত অভ্যন্তরীণ উপস্থাপনা নিরাপদে ব্যবহার করতে পারেন।" যদি না আপনার মেশিন আইইইই ভাসমান পয়েন্ট ফর্ম্যাটটি ব্যবহার না করে ...
জেরি যেরেমিয়া

উত্তর:


8

এমএটিএল , 5 বাইট

3Z%Bz

এটি অনলাইন চেষ্টা করুন!

আমার ম্যাটল্যাব উত্তরের হুবহু লিখিত লিপি নোট করুন যে ইনপুট এবং আউটপুট অন্তর্ভুক্ত। -২ বাইট লুইস মেন্ডোকে ধন্যবাদ।

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 মেশিনের ভাষা (লিনাক্স), 16 বাইট

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

একটি একক -৪-বিট পূর্ণসংখ্যার প্যারামিটার গ্রহণ করে RDI, এটিকে একটি ফ্লোটিং-পয়েন্ট মানকে রূপান্তর করে XMM0, সেই বিটগুলি আবার জমা করে রাখে RAXএবং তারপরে হ্যামিং ওজন গণনা RAXকরে ফলাফলটি ছেড়ে দেয় RAXযাতে এটি কলারে ফিরে যেতে পারে।

এমন একটি প্রসেসরের প্রয়োজন POPCNTযা নির্দেশকে সমর্থন করে , যা হবে ইন্টেল নেহালেম, এএমডি বার্সেলোনা এবং পরবর্তীকালে মাইক্রোআরকিটেকচারস।

অনলাইনে চেষ্টা করার জন্য ! , নিম্নলিখিত সি প্রোগ্রামটি সংকলন এবং চালনা করুন:

#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, কাজের সঠিক সরঞ্জাম! এটি কেবলমাত্র একসময় হতে পারে যে x86 বৈধভাবে গল্ফিংয়ের ভাষাগুলির সাথে প্রতিযোগিতা করতে পারে বা জেলিকে পরাজিত করতে পারে। :)
ডিজেএমসিএমহেম

2
ইও, এটি ও টি সিনট্যাক্স? আপনি objdump -drwC -Mintelইন্টেল সিনট্যাক্সে বিচ্ছিন্ন করতে ব্যবহার করতে পারেন । আপনি যদি একটি রেজিস্টার আপনি দোকান / পুনরায় লোড করার ব্যবহার করতে পারে একটি পয়েন্টার ছিল তাহলে আপনি বাইট বাঁচাতে পারে movaps [rsi], xmm0/ popcnt rax, [rsi]। (মুভিপগুলি কেবল 3 বাইট, মুভাকের চেয়ে 2 টি সংক্ষিপ্ত।) তবে এটি এখানে সহায়তা করে না, কারণ [rsp-24]2 টি অতিরিক্ত বাইট লাগে (আরএসপিটিকে বেস হিসাবে ব্যবহার করতে, ডিসপ্লে 8) লাগে SI এবং সেই অতিরিক্ত বাইটগুলি স্টোর এবং পুনরায় লোড উভয় ক্ষেত্রেই প্রয়োজন। ওহ ভাল, আমি ভেবেছিলাম আমি একটি সঞ্চয়ী দেখেছি, তবে না: /
পিটার কর্ডেস

আমি একটি কাস্টম কলিং কনভেনশন দিয়ে 4 বাইট সংরক্ষণ করেছি । বা এখনও x87 নির্দেশাবলী ব্যবহার করে এটির মতো একই কলিং কনভেনশন সহ 2 বাইট সংরক্ষণ করুন।
পিটার কর্ডেস

1
@ ডিজেএমসিএমহেম: সম্ভবত একমাত্র সময় নয়। এক্সট্রিম ফিবোনাচি চ্যালেঞ্জ সম্পর্কে এখনও কোন গল্ফ-ভাষার উত্তর নেই (ফিবের প্রথম 1000 অঙ্কগুলি (1 বিলিয়ন) এবং আমার এক্স 86 মেশিন কোড উত্তর (দ্রুত 105 বাইট, বা 101 বাইট যা 1 মিনিটের পরিবর্তে 5 মিনিটে চলে) অন্যান্য উত্তরগুলির তুলনায় খুব বেশি বড় নয়, এবং সেগুলি অন্তর্নির্মিত প্রসারণ-পূর্ণ নির্ভুল সংখ্যাসূচক ভাষায় রয়েছে
পিটার কর্ডেস

2
বা একটি সহজ চ্যালেঞ্জ, (এবং কোনও পারফরমেন্সের প্রয়োজনীয়তা ছাড়াই), ক্রোমা-কীটি একটি পূর্ণসংখ্যার অ্যারের মিশ্রণ করে । আমার মেশিন-কোড উত্তর পাইথ উত্তরের অর্ধেক দৈর্ঘ্য।
পিটার কর্ডেস

11

সি (জিসিসি) , 82 68 বাইট

9 বাইট ধন্যবাদ নীলকে।

অশুভ ভাসমান পয়েন্ট বিট স্তর হ্যাকিং

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

এটি অনলাইন চেষ্টা করুন!


আমি জানতাম আপনি প্রথম হবেন, আমি কেবল ভাষাটি আশা করিনি:
লুইস মেন্ডো

@ লুইস মেন্ডো আমি কেবল ভেবেছিলাম যে এটি সেই ভাষায় সুবিধাজনক হবে ... আমি অন্যান্য ভাষাতে এটি করতে পারি তা জানি না
লিকি নুন

2
অন্য উপায়ে স্থানান্তরিত করে 9 বাইট সংরক্ষণ করুন: ... ;long l=... ;l*=2;)s+=l<0;...
নীল

1
এটি অবশ্যই 64-বিট সহ একটি সি বাস্তবায়ন প্রয়োজন long। এটি x86-64 লিনাক্সে কাজ করে তবে উইন্ডোজে ব্যর্থ হয়। আমি " longজিসিসি সঙ্গে 64৪ বিট " বলার পরামর্শ দেব , যেহেতু জিসিসি অনেক প্ল্যাটফর্মে চালিত হয়, যার মধ্যে অনেকগুলি বিভিন্ন এবিআইতে রয়েছে।
পিটার কর্ডেস

1
@ পিটারের মন্তব্যটি কেন আমি একটি সম্পাদনায় "LP64" যুক্ত করেছি। আমি অন্য পাঠ্যটিকে আবারও সাজিয়েছি যা আমি মনে করি এটি আরও যুক্তিসঙ্গত ক্রম। আমার ধারণা আপনি এই পরিবর্তনটি পছন্দ করেন নি এবং এটিকে আবার ঘুরিয়ে দিয়েছিলেন, তবে এলপি 64৪ একটি স্ট্যান্ডার্ড শব্দ যা এটিবিআইকে বর্ণনা করে যেখানে লম্বা এবং পয়েন্টারগুলি -৪-বিট মান (আইএলপি to৪ এর তুলনায় যেখানে ইনটগুলিও 64৪-বিট, বা এলএলপি ,৪, উইন্ডোজে ব্যবহৃত হিসাবে যেখানে কেবল দীর্ঘ দীর্ঘতর এবং পয়েন্টারগুলি 64-বিট এবং লম্বা এখনও 32-বিট থাকে)। হতে পারে আমার আরও ব্যাখ্যা যুক্ত করা উচিত, বা সম্পর্কিত উইকিপিডিয়া নিবন্ধের একটি ইনলাইন লিঙ্ক।
কোডি গ্রে

8

পাইথন 3 , 72 71 বাইট

লিনকে 1 বাইট ধন্যবাদ

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

এটি অনলাইন চেষ্টা করুন!

ব্যাখ্যা

বাইনারি 64 ফর্ম্যাটটিতে তিনটি উপাদান রয়েছে:

  • প্রথম বিটটি হ'ল সাইন বিট, এটি 1যদি সংখ্যাটি নেতিবাচক হয়
  • পরবর্তী 11 বিট 1023 যুক্ত করে এক্সপোঞ্জারটি সঞ্চয় করে
  • পরবর্তী 52 বিটগুলি তাৎপর্য বা ম্যান্টিসার সংরক্ষণ করে।

n and(…)-(n>0)একটি বাইট সংক্ষিপ্ত, না?
লিন

বা ইন্টি>> ফ্লোট, বা কোনও বিষয়ে ভাসমান all
ব্যবহারকারী 2357112 মনিকা 24

8

সি (জিসিসি) , 47 বাইট

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

এটি বহনযোগ্য নয়; এটি জিপিসি 7.1.1 দিয়ে x86_64 চলমান লিনাক্সে, সংকলক পতাকা ছাড়াই পরীক্ষা করা হয়েছিল।

এটি অনলাইন চেষ্টা করুন!


1
ইনপুট একটি পূর্ণসংখ্যা হতে হবে। অথবা এটা জানাতে আহ্বানকারী হ্যান্ডেল যে অন্তর্নিহিত রূপান্তর দ্বারা ঠিক আছে longকাছে doubleকল সাইট এ?
পিটার কর্ডেস

1
এছাড়াও, কম্পাইলার আচরণের একটি অপ্রত্যাশিত সাফল্য উপর নির্ভর ত্যাগ করার ঘটতে nমধ্যে raxআন-অপ্টিমাইজ কোড সহ বেশ গোলগাল হয়। এটি সক্ষম হলে এটি বিরতি দেয় -O3, তাই এটি কেবল সাধারণভাবে সিসিসি নয়, এটি এক্স -8686-64৪-তে জিসিসি optim৪-বিট longসহ অপ্টিমাইজেশন অক্ষম রয়েছে। আপনি যদি এই সমস্ত প্রয়োজনীয়তা আপনার উত্তরটিতে রেখে দেন তবে আমি আপত্তি জানাতে পারি। আমি ধরে নেব যে প্ল্যাটফর্মগুলি জিসিসি সমর্থন রয়েছে যেখানে 64৪-বিট রয়েছে longতবে তার popcountlফলাফলটি রিটার্ন-ভ্যালু রেজিস্টার ব্যতীত অন্য কোনও রেজিস্টারে ছেড়ে যায় ।
পিটার কর্ডেস

1
আমি গাণিতিক দিক দিয়ে পূর্ণসংখ্যা নিয়েছি। আমি আমার পরীক্ষার পরিবেশগুলির চশমাগুলি যুক্ত করেছি, কারণ আমি নিশ্চিত না যে জিসিসি, x86-64, এবং 64-বিট লম্বা যথেষ্ট। এটি বলেছিল, কমপক্ষে x86-এ, রিটার্ন-কম ফাংশনগুলি প্রায়শই না-বেশি জিসিসি (এবং টিসিসি) দিয়ে কাজ করে।
ডেনিস

হ্যাঁ, আমি কেবল প্রশ্নটি পুনরায় পড়ছিলাম এবং আমি সম্মত হলাম যে আর্গোগুলিটি হিসাবে গ্রহণ doubleকরা ঠিক হবে। এটি ফাংশনটি বেস 2 ফর্ম্যাটে এটি গ্রহণ করার প্রয়োজনের বিষয়ে কিছু বলে না। এবং হ্যাঁ, সিসির বিভিন্ন সংস্করণ বিভিন্ন কোড নির্গত করতে পারে তাই এটিও গুরুত্বপূর্ণ। (মজার বিষয়: ছাড়া -mpopcnt, জিসিসি ব্যবহার করবে না popcntinsn, এবং এটি অনুকরণ নির্দেশাবলীর একটি ক্রম নির্গত হবে কিছু আর্কিটেকচারের সব সময়ে একটি popcnt নির্দেশ নেই, তাই। __builtin_popcountlসবসময় insns কিছু ক্রম ব্যবহার করতে আছে)
পিটার Cordes

হ্যাঁ, অনেকগুলি (সবচেয়ে?) __builtin_*ফাংশনগুলির অবৈধ নির্দেশাবলী উত্পাদন এড়ানোর জন্য উত্তরাধিকার সংস্করণ রয়েছে। এটি উপলব্ধ হলেই -march=nativeব্যবহার করে popcntq
ডেনিস


6

সি (জিসিসি), 63 বাইট

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

এই সমাধানটি @ লিকিউন এর উত্তরের উপর ভিত্তি করে তৈরি হয়েছে, তবে তিনি নিজের উত্তরটি উন্নত করতে চান না বলে আমি এখানে আরও গল্ফ সংস্করণ পোস্ট করছি।

এটি অনলাইনে চেষ্টা করুন


2
আমি অত্যন্ত সন্দেহ করি যে কেউ তাদের উত্তর উন্নত করতে চায় না
মিঃ এক্সকোডার

1
@ Mr.Xcoder। ঠিক আছে, আমি নিজের উত্তর সম্পাদনা না করা অবধি এটি এখানে রাখব। তিনি যদি সম্পাদনা করতে না চান, এটি এখানেই থাকবে। আমি তার উত্তরের মন্তব্য হিসাবে এই উন্নতি পোস্ট করেছি এবং তিনি তা প্রত্যাখ্যান করেছেন।

1
আমি মনে করি ইনপুটটি একটি পূর্ণসংখ্যার ধরণের হওয়া উচিত এবং আসল নয়।
সিলিংক্যাট

3
@ পাইরেটবে আমি আমার উত্তর সম্পর্কে আপনার মন্তব্য দেখতে পাইনি এবং আমি এখনও এটি দেখতে পাচ্ছি না।
লিকি নুন

9
উন্নতি সুপারিশ বা আপনার নিজের উত্তর পোস্ট করতে সিদ্ধান্ত পুলিশের, কিন্তু 6 মিনিট কমই হয় প্রায় এক ঘন্টা
ডেনিস

5

সি #, 81 70 68 বাইট

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

@ লিকে নুনকে ধন্যবাদ 11 বাইট সংরক্ষণ করুন।
সংরক্ষিত 2 বাইট @ নীলকে ধন্যবাদ

এটি অনলাইন চেষ্টা করুন! কোডটির System.BitConverter.DoubleToInt64Bitsপরিবর্তে unsafeটিআইওর সাথে কাজ করার জন্য পেলাম না বলে ব্যবহার করে।

সম্পূর্ণ / ফর্ম্যাট সংস্করণ:

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)এবং আপনার ত্রৈমাসিকের প্রয়োজন হবে না
লিকি নুন

@ ল্যাকইনুন ধন্যবাদ আমি যুগে যুগে এটির জন্য আমার মাথা আঁচড়ালাম।
TheLethalCoder

আপনি ব্যবহার করতে পারেন s-=l>>31?
নিল

@ নীল কাজ করতে দেখা যাচ্ছে না। আমি আপনার প্রতিস্থাপন মানে মানে s+=l<0?1:0?
TheLethalCoder

আমার খারাপ; lএকটি দীর্ঘ, তাই এটি প্রয়োজন s-=l>>63?
নিল

4

পাইথন 2 , 69 বাইট

-12 বাইটস, কেবলমাত্র @ ASCII- এর জন্য ধন্যবাদ

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

এটি অনলাইন চেষ্টা করুন!




@ মিঃ এক্সকোডার !দরকার নেই যেহেতু বাইট অর্ডার এখানে গুরুত্বপূর্ণ নয়
ASCII-


@ এএসসিআইআই-অন প্যাকযুক্ত প্যাক করুন। ধন্যবাদ: ডি
ডেড পসসাম

4

জাভাস্ক্রিপ্ট (ES6), 81 80 77 বাইট

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

সম্পাদনা: @ আরনাউল্ডকে ধন্যবাদ 1 বাইট সংরক্ষিত @ ডকম্যাক্সকে ধন্যবাদ 3 বাইট সংরক্ষণ করা হয়েছে।


আপনি g(i^i&-i,x++)-1 বাইট জন্য করতে পারেন ?
আর্নল্ড

@ আরনাউল্ড আমি অবাক করেছিলাম যে সেখানে কোনও গল্ফিয়ার বিট টুডল ছিল কিনা এটি সন্ধানের জন্য ধন্যবাদ!
নীল

1
-3 আপনি যদি এর new Float64Array([n])সাথে প্রতিস্থাপন করেনFloat64Array.of(n)
ডকম্যাক্স

4

x86-64 মেশিন কোড, int64_tইনপুট জন্য 12 বাইট

doubleইনপুট জন্য 6 বাইট

popcntআইএসএ এক্সটেনশন প্রয়োজন ( CPUID.01H:ECX.POPCNT [Bit 23] = 1)।

(অথবা জায়গায় জায়গায় আর্গটি সংশোধন করার জন্য উপরের 32 টিতে আবর্জনা না রেখে সমস্ত 64-বিট লেখার প্রয়োজন। আমি যুক্তিযুক্ত যুক্তিসঙ্গত মনে করি যে কলার সম্ভবত যে কোনও উপায়ে কম 32b লোড করতে চান এবং x86 শূন্য - প্রতিটি 32-বিট ক্রিয়াকলাপের সাথে স্পষ্টভাবে 32 থেকে 64 পর্যন্ত প্রসারিত হয় Still তবুও, এটি কলার add rbx, [rdi]বা কিছু করতে বাধা দেয় না ))

x87 নির্দেশাবলী আরও সুস্পষ্ট এসএসই 2cvtsi2sd / movq( @ সিলিংক্যাট এর উত্তরে ব্যবহৃত ) এর চেয়ে কম , এবং একটি [reg]ঠিকানা মোড একই আকার reg: কেবলমাত্র একটি মোড / আরএম বাইট।

কৌশলটি মোডে অ্যাড্রেস করার জন্য খুব বেশি বাইটের প্রয়োজন ছাড়াই মেমোরিতে পাস করার একটি উপায় নিয়ে আসছিল। (যেমন: স্ট্যাকের উপর দিয়ে যাওয়া এত বড় নয়)) ভাগ্যক্রমে, নিয়মগুলি আরগগুলি পড়ার / লেখার অনুমতি দেয় বা পৃথক আউটপুট আরোগুলি দেয় , তাই আমি কেবল কলারকে আমার স্মৃতিতে একটি পয়েন্টার পাস করতে পারি যেটা আমি লিখতে পারি।

সি থেকে স্বাক্ষর সহ আহ্বানযোগ্য: void popc_double(int64_t *in_out); ফলাফলের কেবলমাত্র কম 32b বৈধ, যা সি এর জন্য অদ্ভুত তবে এএসএমের জন্য প্রাকৃতিক। (এটি স্থির করার জন্য চূড়ান্ত স্টোরের একটি আরএক্স উপসর্গ প্রয়োজন ( mov [rdi], rax), তাই আরও একটি বাইট)) উইন্ডোজে, পরিবর্তন rdiকরুন rdx, কারণ উইন্ডোজ x86-64 সিস্টেম ভি এবিআই ব্যবহার করে না।

এনএএসএম তালিকা। টিআইও লিঙ্কে বিচ্ছিন্নতা ছাড়াই উত্স কোড রয়েছে।

  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

এটি অনলাইন চেষ্টা করুন! একটি_startপরীক্ষা প্রোগ্রাম অন্তর্ভুক্ত করে যা এটিকে একটি মান দেয় এবং প্রস্থান স্থিতি = পপকন্টের ফেরতের মান সহ প্রস্থান করে। (এটি দেখতে "ডিবাগ" ট্যাবটি খুলুন))

পৃথক ইনপুট / আউটপুট পয়েন্টারগুলি পাস করাও (x86-64 সিস্টেমভি এবিআইতে rdi এবং rsi) কাজ করতে পারে তবে আমরা যুক্তিসঙ্গতভাবে -৪-বিট ইনপুটটি ধ্বংস করতে পারি না বা কেবলমাত্র লেখার সময় একটি -৪-বিট আউটপুট বাফারের প্রয়োজনীয়তা প্রমাণ করতে পারি না কম 32 বি।

আমরা যুক্তি দিতে চাই যে আমরা ইনপুট পূর্ণসংখ্যা একটি পয়েন্টার গ্রহণ করা এবং তা ধ্বংস করতে পারেন যখন আউটপুট ফিরে চান না rax, তারপর কেবল বাদ mov [rdi], eaxথেকে popcnt_double_outarg, 10 বাইট এটিকে নিচে এনে দেয়।


নির্বোধ কলিং-কনভেনশন কৌশল, 14 বাইট ব্যতীত বিকল্প

স্ট্যাকটি সেখানে পৌঁছানোর সাথে স্ক্র্যাচ স্পেস হিসাবে ব্যবহার করুন push। 3 এর পরিবর্তে 2 বাইটে নিবন্ধগুলি অনুলিপি করতে push/ ব্যবহার করুন । ( সর্বদা একটি এসআইবি বাইট প্রয়োজন, তাই এটি ব্যবহারের জন্য তিনটি নির্দেশের আগে অনুলিপি করতে 2 বাইট ব্যয় করা উচিত ))popmov rdi, rsp[rsp]rsp

সি থেকে এই স্বাক্ষরের সাথে কল করুন: 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.

doubleফর্ম্যাট ইনপুট গ্রহণ

প্রশ্নটি কেবলমাত্র এটি একটি নির্দিষ্ট পরিসরে একটি পূর্ণসংখ্যা, এটি বেস 2 বাইনারি পূর্ণসংখ্যার উপস্থাপনায় থাকতে হবে তা নয়। doubleইনপুট গ্রহণ করার অর্থ x x আর ব্যবহার করার কোনও মানে নেই। (আপনি যদি কোনও কাস্টম কলিং কনভেনশন ব্যবহার না করেন যেখানে doubleএক্স ৮87৮ রেজিস্টারে পাস করা হয় Then

11 বাইট:

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

তবে আমরা 6-বাইট সংস্করণ তৈরি করার জন্য আগের মতো একই পাস-বাই-রেফারেন্স ট্রিকটি ব্যবহার করতে পারি: int pcd(const double&d);

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

6 বাইট



3

ম্যাটল্যাব, 36 বাইট

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

এই তথ্যটি ব্যবহার করে যা de2biকেবলমাত্র সংক্ষিপ্ত dec2binনয়, এটি ASCII 48, 49 এর চেয়ে বেশি এবং শূন্যগুলির একটি ফলাফল সরবরাহ করে।


3

জাভা (,৪, ,১, ৪১ বাইট)

স্ট্যান্ডার্ড লাইব্রেরি (জাভা এসই 5+) ব্যবহার করে সম্পূর্ণ সোজা:

int f (দীর্ঘ n) Long প্রত্যাবর্তন দীর্ঘ। বিটকাউন্ট (ডাবল। ডাবলটোলংবিটস (এন));}

কেভিন ক্রুইজসেন (জাভা এসই 5+) এর অবদান:

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

কেভিন ক্রুইজসেন (জাভা এসই 8+, ল্যাম্বডা ফাংশন) এর অবদান:

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

সুন্দরভাবে সম্পন্ন! :-)
লিকি নুন

1
ভাল উত্তর, আমার কাছ থেকে +1। প্যারামিটারটি হিসাবে নিয়ে আপনি তিনটি বাইট গল্ফ করতে পারেন Long nএবং n.bitCount(...)পরিবর্তে ব্যবহার করতে পারেন Long.bitCount(...)। এছাড়াও, আপনি যদি জাভা 8+ ব্যবহার করেন তবে আপনি এটিকে গল্ফ করতে পারেন n->n.bitCount(Double.doubleToLongBits(n))( 41 বাইট )
কেভিন ক্রুইজসেন

2

কেবলমাত্র অন্যরকম, নিরাপদ- লেথলকোডারের পদ্ধতির চেষ্টা করার জন্য, আমি এটি নিয়ে এসেছি (এটি একটি করুণ সি # এর দীর্ঘ পদ্ধতির নাম রয়েছে):

সি # (.নেট কোর) , 76 + 13 বাইট

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

এটি অনলাইন চেষ্টা করুন!

বাইট গণনায় 13 বাইট অন্তর্ভুক্ত using System;। প্রথমে আমি রূপান্তর করতে হবে doubleএকটি করতে longএকই বাইনারি উপস্থাপনা আছে, তারপর আমি এটি একটি বাইনারি রূপান্তর করতে পারেন string, এবং তারপর আমি গণনা 1STRING এবং সাবস্ট্রিং বিয়োগ 1 বেড়ে চলেছে বিভাজন দ্বারা শুধু s।


দুর্দান্ত বিকল্প তবে আপনাকে এটি usingআপনার বাইট গণনায় অন্তর্ভুক্ত করতে হবে।
TheLethalCoder

95 জন্য Linq ব্যবহারের জন্য শুধুমাত্র আরো কয়েকটি বাইট: namespace System.Linq;{d=>Convert.ToString(BitConverter.DoubleToInt64Bits(d),2).Count(c=>c>48)}। যদিও আমি এটি পরীক্ষা করেছি না, এটি কাজ করা উচিত।
TheLethalCoder

@ লেথলকোডার এটি কাজ করে, তবে আমি লিনককে এড়াতে চেষ্টা করেছি যাতে আমাকে দ্বিতীয় usingনির্দেশিকা যুক্ত করতে না হয় ।
চার্লি

1
যখন আপনি দ্বিতীয়টি যুক্ত করবেন যখন এটি কার্যকর হবে namespace। তবে হ্যাঁ এই ক্ষেত্রে লিঙ্ককে এড়ানো কিছুটা সস্তা ছিল। আপনার বাইটগুলি বাঁচাতে কীভাবে এটি ছোট করা যায় সে সম্পর্কে আপনার কোনও ধারণা থাকলে সেক্ষেত্রে কেবলমাত্র এর পদ্ধতির সাথে মন্তব্য করতে চেয়েছি।
TheLethalCoder

@ দ্য লেথলকোডার, Sum(c=>c&1)ছোট। বাSum()-768
পিটার টেলর 11


1

ডিসি, 79 বাইট

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

আউটপুট স্ট্যাকের উপরে রেখে গেছে।
আমি পরে একটি ব্যাখ্যা যোগ করব।

এটি অনলাইন চেষ্টা করুন!

মনে রাখবেন যে negativeণাত্মক সংখ্যাগুলি আগে রয়েছে _, নয় -



1

সি, 67 বাইট

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

নিয়ন্ত্রণ কোড এবং ফলাফল

#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

1

55 বাইট এরলং

fun(X)->length([Y||<<Y:1>><=<<X:64/float>>,Y=:=1])end.

একটি বেনাম ফাংশন যা 164 টি বিট ফ্লোট হিসাবে এনকোড করা একটি সংখ্যায় সমস্ত গুলিকে গণনা করে ।

রেফারেন্স:

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.