x86-64 Машинний код, 26 байт
31 C9 8D 71 01 89 F8 FF C1 99 F7 F9 85 D2 75 03 0F AF F1 39 F9 7C EE 89 F0 C3
Вищевказаний код визначає функцію, яка приймає єдиний параметр (вхідне значення, додатне ціле число) в EDI
(дотримуючись конвенції виклику System V AMD64, що використовується для Gnu / Unix), і повертає єдиний результат (добуток дільників) у EAX
.
Внутрішньо він обчислює добуток дільників, використовуючи (вкрай неефективний) ітеративний алгоритм, подібний поданню C pizzapants184 . В основному, він використовує лічильник для перегляду всіх значень між 1 та вхідним значенням, перевіряючи, чи є поточне значення лічильника дільником введення. Якщо це так, він множить це на поточний загальний продукт.
Мнемоніка невмілої мови монтажу:
; Parameter is passed in EDI (a positive integer)
ComputeProductOfDivisors:
xor ecx, ecx ; ECX <= 0 (our counter)
lea esi, [rcx + 1] ; ESI <= 1 (our running total)
.CheckCounter:
mov eax, edi ; put input value (parameter) in EAX
inc ecx ; increment counter
cdq ; sign-extend EAX to EDX:EAX
idiv ecx ; divide EDX:EAX by ECX
test edx, edx ; check the remainder to see if divided evenly
jnz .SkipThisOne ; if remainder!=0, skip the next instruction
imul esi, ecx ; if remainder==0, multiply running total by counter
.SkipThisOne:
cmp ecx, edi ; are we done yet? compare counter to input value
jl .CheckCounter ; if counter hasn't yet reached input value, keep looping
mov eax, esi ; put our running total in EAX so it gets returned
ret
Справа в тому, що IDIV
інструкція використовує жорстко закодовані операнди для дивідендів, що трохи стискають мій стиль, але я думаю, що це досить добре для мови, яка не має вбудованих, а базових арифметичних та умовних гілок!