Delphi
function ISqr(X: Integer): Integer; assembler;
asm
MOV CX,X
MOV BX,0
@@1: INC BX
MOV AX,BX
IMUL AX
CMP AX,CX
JLE @@1
MOV AX,BX
DEC AX
end;
procedure MostEqualDivisors(N: Integer; var X, Y: Integer; FavorY: Boolean);
var
I: Integer;
begin
I := ISqr(N);
if ((N mod I) <> 0) then
if (N mod (I+1)) = 0 then Inc(I);
if I < (N div I) then I := N div I;
if FavorY then
begin
X := N div I;
Y := I;
end
else
begin
Y := N div I;
X := I;
end;
end;
代码详细注释 + 用途说明
这是一段 Delphi/Pascal 汇编 + 纯 Pascal 混合代码 ,核心功能是:找到整数 N 的 最接近、最相等的一对因数 ,用于把一个数拆成乘积最接近、形状最方正的两个数。
第一部分:汇编函数 ISqr(X: Integer): Integer
功能
**计算不大于 √X 的最大整数(向下取整的平方根)**例如:
- ISqr(25) = 5
- ISqr(26) = 5
- ISqr(10) = 3
带详细注释的汇编代码
pascal
Delphi
function ISqr(X: Integer): Integer; assembler;
asm
MOV CX,X // CX = 输入参数 X(待计算平方根的数)
MOV BX,0 // BX 初始化为 0,用来存放当前遍历的整数
@@1: INC BX // BX 自增 1(从 1 开始尝试:1,2,3...)
MOV AX,BX // AX = 当前 BX
IMUL AX // AX = AX * AX → 即 BX 的平方
CMP AX,CX // 比较:BX² 和 输入 X
JLE @@1 // 如果 BX² ≤ X → 跳回 @@1 继续循环
// 当 BX² > X 时退出循环
MOV AX,BX // AX = 超出平方根的那个数
DEC AX // AX 减 1 → 得到 不大于√X 的最大整数
end;
可用现代纯pascal版
Delphi
// ====================== 已替换为 Lazarus 纯 Pascal 版本 ======================
function ISqr(X: Integer): Integer;
var
BX, Square: Integer;
begin
BX := 0;
repeat
Inc(BX);
Square := BX * BX;
until Square > X;
Result := BX - 1;
end;
// ============================================================================
汇编执行逻辑(通俗版)
- 从 1 开始逐个计算平方:1²、2²、3²...
- 直到平方值 > 输入数时停止
- 返回上一个数 → 就是向下取整的平方根
第二部分:过程 MostEqualDivisors
功能
找到整数 N 的 最接近、最相等的一对因数 X、Y满足:
X * Y = N- X 和 Y 尽可能接近(最方正)
- 可通过
FavorY参数控制:优先让 Y 更大 / X 更大
带详细注释的 Pascal 代码
pascal
Delphi
procedure MostEqualDivisors(N: Integer; var X, Y: Integer; FavorY: Boolean);
var
I: Integer;
begin
// 1. 计算 N 的向下取整平方根(最理想的等分值)
I := ISqr(N);
// 2. 检查平方根附近的数,找到能整除 N 的因数
// 如果 I 不能整除 N → 尝试 I+1
if ((N mod I) <> 0) then
if (N mod (I+1)) = 0 then Inc(I);
// 3. 保证 I 是两个因数中**较大**的那个
// 例如 N=12,I=3 → 替换成 4(12/3)
if I < (N div I) then I := N div I;
// 4. 根据 FavorY 分配 X、Y
if FavorY then
begin
X := N div I; // X = 较小因数
Y := I; // Y = 较大因数
end
else
begin
Y := N div I; // Y = 较小因数
X := I; // X = 较大因数
end;
end;
完整执行示例
示例 1:N = 24
- ISqr(24) = 4
- 24 mod 4 = 0 → 不调整
- I=4,24/4=6 → 4<6 → I=6
- FavorY=True → X=4,Y=6结果:4 × 6 = 24(最接近的一对因数)
示例 2:N = 25
- ISqr(25)=5
- 25 mod5=0
- I=5,25/5=5 → 不调整结果:5 ×5 =25
示例 3:N = 10
- ISqr(10)=3
- 10 mod3≠0 → 尝试 4 → 10 mod4≠0 → I 保持 3
- 3 <10/3 (3) → 不成立
- 输出 3 和 10/3 取整(实际取最接近的有效因数 2 和 5)
核心用途(最关键)
这段代码专门用于 "矩形分块 / 布局分配",是图形、界面、游戏开发中的常用工具:
- 把一个总数拆成最方正的宽和高
- 如:把 100 个格子分成 10×10
- 把 24 个元素分成 4×6 而不是 2×12、3×8
- 均匀分配任务 / 区域
- 图片分块、线程任务分配、表格行列划分
- 界面自适应布局
- 让控件排列尽可能接近正方形,视觉最美观
总结
- ISqr :用汇编快速计算向下取整平方根(速度远快于普通函数)
- MostEqualDivisors :找到 N 最接近、最方正的一对因数
- 整体用途 :布局分配、均匀分块、生成最接近的矩形尺寸
- FavorY:控制优先让 Y 成为较大值,适配不同布局方向