IA-32机器代码,27个字节
十六进制转储:
60 33 db 8b f9 33 c0 92 43 50 f7 f3 85 d2 75 04
ab 93 ab 93 3b c3 5a 77 ec 61 c3
源代码(MS Visual Studio语法):
pushad;
xor ebx, ebx;
mov edi, ecx;
myloop:
xor eax, eax;
xchg eax, edx;
inc ebx;
push eax;
div ebx;
test edx, edx;
jnz skip_output;
stosd;
xchg eax, ebx;
stosd;
xchg eax, ebx;
skip_output:
cmp eax, ebx;
pop edx;
ja myloop;
popad;
ret;
第一个参数(ecx
)是要输出的指针,第二个参数(edx
)是数字。它不会以任何方式标记输出的结束。应该用零预填充输出数组以找到列表的末尾。
使用此代码的完整C ++程序:
#include <cstdint>
#include <vector>
#include <iostream>
#include <sstream>
__declspec(naked) void _fastcall doit(uint32_t* d, uint32_t n) {
_asm {
pushad;
xor ebx, ebx;
mov edi, ecx;
myloop:
xor eax, eax;
xchg eax, edx;
inc ebx;
push eax;
div ebx;
test edx, edx;
jnz skip_output;
stosd;
xchg eax, ebx;
stosd;
xchg eax, ebx;
skip_output:
cmp eax, ebx;
pop edx;
ja myloop;
popad;
ret;
}
}
int main(int argc, char* argv[]) {
uint32_t n;
std::stringstream(argv[1]) >> n;
std::vector<uint32_t> list(2 * sqrt(n) + 3); // c++ initializes with zeros
doit(list.data(), n);
for (auto i = list.begin(); *i; ++i)
std::cout << *i << '\n';
}
即使遵循规范,输出也会出现一些小故障(无需排序;无需唯一性)。
输入:69
输出:
69
1
23
3
除数成对出现。
输入:100
输出:
100
1
50
2
25
4
20
5
10
10
对于完美的平方,最后的除数输出两次(与自身成对)。
输入:30
输出:
30
1
15
2
10
3
6
5
5
6
如果输入接近理想平方,则最后一对输出两次。这是因为循环中检查的顺序:首先,它检查“ remainder = 0”并输出,然后才检查“ quotient <除数”以退出循环。
O(sqrt(n))
。