整数最接近等因数分解函数(汇编优化版)

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 开始逐个计算平方:1²、2²、3²...
  2. 直到平方值 > 输入数时停止
  3. 返回上一个数 → 就是向下取整的平方根

第二部分:过程 MostEqualDivisors

功能

找到整数 N 的 最接近、最相等的一对因数 X、Y满足:

  1. X * Y = N
  2. X 和 Y 尽可能接近(最方正)
  3. 可通过 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

  1. ISqr(24) = 4
  2. 24 mod 4 = 0 → 不调整
  3. I=4,24/4=6 → 4<6 → I=6
  4. FavorY=True → X=4,Y=6结果:4 × 6 = 24(最接近的一对因数)

示例 2:N = 25

  1. ISqr(25)=5
  2. 25 mod5=0
  3. I=5,25/5=5 → 不调整结果:5 ×5 =25

示例 3:N = 10

  1. ISqr(10)=3
  2. 10 mod3≠0 → 尝试 4 → 10 mod4≠0 → I 保持 3
  3. 3 <10/3 (3) → 不成立
  4. 输出 3 和 10/3 取整(实际取最接近的有效因数 2 和 5)

核心用途(最关键)

这段代码专门用于 "矩形分块 / 布局分配",是图形、界面、游戏开发中的常用工具:

  1. 把一个总数拆成最方正的宽和高
    • 如:把 100 个格子分成 10×10
    • 把 24 个元素分成 4×6 而不是 2×12、3×8
  2. 均匀分配任务 / 区域
    • 图片分块、线程任务分配、表格行列划分
  3. 界面自适应布局
    • 让控件排列尽可能接近正方形,视觉最美观

总结

  1. ISqr :用汇编快速计算向下取整平方根(速度远快于普通函数)
  2. MostEqualDivisors :找到 N 最接近、最方正的一对因数
  3. 整体用途 :布局分配、均匀分块、生成最接近的矩形尺寸
  4. FavorY:控制优先让 Y 成为较大值,适配不同布局方向
相关推荐
用户18806874935219 分钟前
戴着 Rokid 接成语:用 AIUI 做一局有提示、有复盘的“接着说”
前端
Sakura_j_h_28 分钟前
Three.js 单文件离线机械臂工作台:爆炸图、透明外壳与剖面
前端·机械臂·webgl·three.js·1024程序员节·esbuild
2401_885885042 小时前
国际语音C#接口怎么写?.NET环境下实现国际语音验证码批量下发
开发语言·c#·.net
计算机魔术师2 小时前
管谷歌的不是Pichai一个人,是一整层AI智能体
前端
米米商聊2 小时前
图标能点,按钮就可用了吗?键盘、名称与收藏状态
前端·javascript
程序猿乐锅2 小时前
【从0-1学习Python | 第七篇】Python 面向对象基础
开发语言·笔记·后端·python·学习·1024程序员节
Wang's Blog2 小时前
Java 项目实战: 交友项目 - 查询圈子个人动态:查询我的动态需求分析
java·开发语言·交友
凯瑟琳.奥古斯特2 小时前
力扣1016高效解法:剪枝优化技巧
开发语言·c++·算法·leetcode·职场和发展
Younglina3 小时前
三个晚上,我和 WorkBuddy 做了个生图网站
前端·后端·ai编程
xy34533 小时前
Axure 9.0 内联框架加载方式
前端·ui·html·axure·原型·产品设计