x86-64 মেশিন কোড ফাংশন, 40 বাইট।
অথবা যদি 0 বনাম শূন্য-শূন্যটি স্ট্রিম্পের মতো "সত্যবাদী" হিসাবে অনুমোদিত হয় তবে 37 বাইট।
বিটম্যাপ ধারণার জন্য কার্ল নেপফের সি উত্তরের জন্য ধন্যবাদ, যা বিটিএসের সাথে x86 খুব দক্ষতার সাথে করতে পারে ।
ফাংশন স্বাক্ষর: _Bool cube_digits_same(uint64_t n);
x86-64 সিস্টেম ভি এবিআই ব্যবহার করে। ( n
আরডিআই-তে, আলিতে বুলিয়ান রিটার্ন মান (0 বা 1))।
_Bool
আইএসও সি 11 দ্বারা সংজ্ঞায়িত করা হয় এবং সাধারণত সি ++ এর মতো একই শব্দার্থবিজ্ঞানের সাথে #include <stdbool.h>
সংজ্ঞা দিতে ব্যবহৃত হয় ।bool
bool
সম্ভাব্য সঞ্চয়:
- 3 বাইট: বিপরীত শর্তটি ফিরিয়ে দেওয়া (কোনও পার্থক্য থাকলে শূন্য নয়)। বা ইনলাইন asm থেকে: একটি পতাকা শর্ত ফেরত (যা gcc6 দিয়ে সম্ভব)
- 1 বাইট: যদি আমরা ইবিএক্স ক্লোবার করতে পারি (এটি করার ফলে এই ফাংশনটি একটি মানহীন কলিং কনভেনশন দেয়)। (ইনলাইন asm থেকে এটি করতে পারে)
- 1 বাইট: আরইটি নির্দেশনা (ইনলাইন asm থেকে)
এগুলি সমস্তই সম্ভব যদি এটি কোনও ফাংশনের পরিবর্তে কোনও ইনলাইন-এসএম খণ্ড ছিল, যা এটি ইনলাইন-এসএমের জন্য 35 বাইট করে ।
0000000000000000 <cube_digits_same>:
0: 89 f8 mov eax,edi
2: 48 f7 e7 mul rdi # can't avoid a REX prefix: 2642245^2 doesn't fit in 32 bits
5: 48 f7 e7 mul rdi # rax = n^3, rdx=0
8: 44 8d 52 0a lea r10d,[rdx+0xa] # EBX would save a REX prefix, but it's call-preserved in this ABI.
c: 8d 4a 02 lea ecx,[rdx+0x2]
000000000000000f <cube_digits_same.repeat>:
f: 31 f6 xor esi,esi
0000000000000011 <cube_digits_same.cube_digits>:
11: 31 d2 xor edx,edx
13: 49 f7 f2 div r10 ; rax = quotient. rdx=LSB digit
16: 0f ab d6 bts esi,edx ; esi |= 1<<edx
19: 48 85 c0 test rax,rax ; Can't skip the REX: (2^16 * 10)^3 / 10 has all-zero in the low 32.
1c: 75 f3 jne 11 <cube_digits_same.cube_digits>
; 1st iter: 2nd iter: both:
1e: 96 xchg esi,eax ; eax=n^3 bitmap eax=n bitmap esi=0
1f: 97 xchg edi,eax ; edi=n^3 bitmap, eax=n edi=n bmp, eax=n^3 bmp
20: e2 ed loop f <cube_digits_same.repeat>
22: 39 f8 cmp eax,edi
24: 0f 94 d0 sete al
;; The ABI says it's legal to leave garbage in the high bytes of RAX for narrow return values
;; so leaving the high 2 bits of the bitmap in AH is fine.
27: c3 ret
0x28: end of function.
LOOP মনে হচ্ছে একবারে পুনরাবৃত্তি করার সবচেয়ে ছোট উপায় way আমি কেবল লুপটি পুনরাবৃত্তি করতে দেখেছি (আরএক্স উপসর্গগুলি এবং একটি ভিন্ন বিটম্যাপ নিবন্ধ ছাড়া) তবে এটি কিছুটা বড়। আমি পুশ আরএসআই ব্যবহার করে এবং একবার test spl, 0xf
/ jz
টু লুপ ব্যবহার করেও চেষ্টা করেছি (যেহেতু এবিআইয়ের প্রয়োজন যে আরএসপি কল করার আগে 16 বি সারিবদ্ধ, সুতরাং একটি ধাক্কা এটি সারিবদ্ধ করে, এবং অন্য একটি এটি আবার মিসিলিন করে)। কোনও test r32, imm8
এনকোডিং নেই, তাই সবচেয়ে ছোট উপায়টি ছিল একটি 4 ই টি টেস্ট নির্দেশ (একটি রেক্স প্রেফিক্স সহ) সাথে কোনও প্রতিরোধের বিরুদ্ধে আরএসপির ঠিক কম বাইট পরীক্ষা করার জন্য। এলইএ + লুপ হিসাবে একই আকার, তবে অতিরিক্ত পুশ / পিওপি নির্দেশাবলী প্রয়োজন।
স্ট্যান্ডিবক্সের সি প্রয়োগকরণ (বনাম স্টাডিবক্সের সি প্রয়োগকরণের জন্য পরীক্ষার ব্যাপ্তিতে সমস্ত এন এর জন্য পরীক্ষিত) (যেহেতু এটি একটি পৃথক অ্যালগরিদম ব্যবহার করে)। আমি ভিন্ন ভিন্ন ফলাফলের দুটি ক্ষেত্রেই দেখেছি, আমার কোডটি সঠিক ছিল এবং স্ট্যাডিবক্সগুলি ভুল ছিল। আমি মনে করি আমার কোডটি সকল এন এর জন্য সঠিক।
_Bool cube_digits_same(unsigned long long n);
#include <stdio.h>
#include <stdbool.h>
int main()
{
for(unsigned n=0 ; n<= 2642245 ; n++) {
bool c = f(n);
bool asm_result = cube_digits_same(n);
if (c!=asm_result)
printf("%u problem: c=%d asm=%d\n", n, (int)c, (int)asm_result);
}
}
কেবলমাত্র মুদ্রিত লাইনে সি = 1 asm = 0 রয়েছে: সি অ্যালগরিদমের জন্য মিথ্যা-ধনাত্মক।
uint64_t
একই সাথে অ্যালগরিদমের কার্ল সি প্রয়োগকরণের একটি সংস্করণের বিরুদ্ধেও পরীক্ষিত হয়েছিল এবং ফলাফলগুলি সমস্ত ইনপুটগুলির সাথে মেলে।