☰
仓颉编程语言 std.math 数学基础运算实战:clamp、gcd、lcm 与 rotate 详解
2026/10/14 3:16:02 网站建设 项目流程
  • 文档
  • 知识库
  • 教程
  • OpenHarmony

【免费下载链接】CangjieCorpus

本仓库为仓颉编程语言语料库,聚焦 仓颉编程语言 核心知识体系,整合官方开发指南、API 文档、典型代码示例及语法规范等多维度资源,经结构化处理与专业标注,构建为支持 RAG(检索增强生成)技术 的高质量知识基座,适配智能编码助手、学习辅助工具等应用开发需求。 欢迎开发者基于本语料库构建仓颉语言智能应用,推动鸿蒙开发生态智能化升级!

项目地址:https://gitcode.com/Cangjie/CangjieCorpus
点击查看免费下载

导读

本文以仓颉编程语言标准库std.math包中的四个高频基础运算函数——范围截断clamp、最大公约数gcd、最小公倍数lcm、按位旋转rotate为核心,结合 math_basic_operation.md 示例与 math_package_funcs.md API 文档,逐函数讲解其函数签名、参数语义、返回值规则、异常边界与可运行示例。读完本文,你将能够直接在仓颉工程中正确导入并调用这四个函数,处理数值限幅、分数化简、周期计算与位级数据变换等典型场景。

一、std.math 包概览

std.math是仓颉标准库中的数学工具包,在 math_package_overview.md 中将其能力划分为五类:

  1. 科学常数与类型常数定义(如E、PI等浮点常数属性);
  2. 浮点数的判断与规整(isNaN、isInf、normalize等);
  3. 常用的位运算(rotate、reverse、countOnes、leadingZeros、trailingZeros等);
  4. 通用的数学函数(绝对值、三角函数、指数、对数、开方、幂运算等);
  5. 最大公约数与最小公倍数(gcd、lcm)。

其中clamp属于范围截断类工具函数。这些函数均为顶层公开函数(public func),使用时需按函数粒度精确导入,例如import std.math.clamp、import std.math.gcd、import std.math.lcm、import std.math.rotate,而不能使用包级通配导入。

二、clamp:浮点数范围截断

2.1 函数签名与语义

clamp将输入值限制在[min, max]闭区间内,为Float16、Float32、Float64三种浮点类型各提供一版重载,以Float16为例(源码定义):

public func clamp(v: Float16, min: Float16, max: Float16): Float16

参数与返回值规则:

参数/返回值含义
v传入的需要截断的浮点数
min指定范围区间的最小值
max指定范围区间的最大值
返回值v在区间内则返回v;v小于等于min返回min;v大于等于max返回max;v为NaN时返回NaN

异常:当min大于max,或min、max中存在NaN时,抛出 IllegalArgumentException。

2.2 边界行为分析

clamp的三个典型分支在示例中均有覆盖(示例源码):

  • 值在区间内:v = 0.121、区间[-0.123, 0.123],返回值等于v;
  • 值超过上界:v = 11.121大于max2 = 10.123,返回max2;
  • 值低于下界:v = -1.121小于min3 = -0.999,返回min3。
import std.math.clamp func clampTest() { let min: Float16 = -0.123 let max: Float16 = 0.123 let v: Float16 = 0.121 let c = clamp(v, min, max) println("${c==v}") let min2: Float16 = -0.999 let max2: Float16 = 10.123 let v2: Float16 = 11.121 let c2 = clamp(v2, min2, max2) println("${c2==max2}") let min3: Float16 = -0.999 let max3: Float16 = 10.123 let v3: Float16 = -1.121 let c3 = clamp(v3, min3, max3) println("${c3==min3}") }

注意NaN的传递性:若v本身是NaN,返回值仍是NaN(NaN与任何值的比较结果都为假,因此需要专门处理);而若min/max为NaN则直接抛出IllegalArgumentException,这是调用时最容易踩的坑。

三、gcd:最大公约数

3.1 函数签名与语义

gcd为Int8、Int16、Int32、Int64及UInt8、UInt16、UInt32、UInt64共 8 种整数类型提供重载,以Int16为例(源码定义):

public func gcd(x: Int16, y: Int16): Int16

参数x、y为需要计算最大公约数的两个整数,返回两者(非负)最大公约数。

异常边界:当两个参数同时为有符号整数最小值,或一个参数为有符号整数最小值且另一个参数为 0时,抛出 IllegalArgumentException。原因在于对最小值取绝对值会溢出该类型表示范围,无法安全计算。

3.2 示例与结果

示例中的两个用例恰好体现了 gcd 对负数与零的处理(示例源码):

import std.math.gcd func gcdTest() { let c2 = gcd(0, -60) println("c2=${c2}") let c4 = gcd(-33, 27) println("c4=${c4}") }

运行结果:

c2=60 c4=3
  • gcd(0, -60)返回60:当入参含 0 时,公约数取另一参数的绝对值,说明 gcd 的结果恒为非负;
  • gcd(-33, 27)返回3:负数入参先取绝对值再计算,33与27的最大公约数为3。

四、lcm:最小公倍数

4.1 函数签名与语义

lcm同样覆盖 8 种整数类型,以Int8为例(源码定义):

public func lcm(x: Int8, y: Int8): Int8

返回值规则:返回两个整数的最小的非负公倍数;只有当入参有 0 时才返回 0(这与某些语言实现不同,需特别留意)。

异常:当计算结果超出当前整数类型的最大值时抛出 IllegalArgumentException。这意味调用前应预估lcm的数值量级,避免溢出,例如两个接近Int8.MAX的数相乘极易越界。

4.2 示例与结果

import std.math.lcm func lcmTest() { let a: Int8 = lcm(Int8(-3), Int8(5)) println("a=${a}") }

运行结果:

a=15

lcm(-3, 5)返回15:虽然入参含负数,但结果取非负公倍数。由lcm(x, y) = |x * y| / gcd(x, y)可知,3与5互质,其最小公倍数为15,与gcd(0, -60)=60形成对照:gcd 与 lcm 互为配套的整数值运算,常用于分数约分、周期对齐等场景。

五、rotate:整数按位旋转

5.1 函数签名与语义

rotate将整数的二进制位按循环方式旋转,覆盖全部 8 种整数类型,以Int8为例(源码定义):

public func rotate(num: Int8, d: Int8): Int8

参数说明(API 文档):

参数含义
num传入一个整数
d旋转位数,负数右移,正数左移

旋转(rotate)与普通移位(shift)的关键区别在于:移出的高位/低位不会被丢弃,而是从另一端循环补回,因此位数本身不会丢失,特别适合校验码计算、哈希扩散、加密类位级变换等场景。

5.2 示例结果的手工验证

import std.math.rotate func rotateTest() { let a: Int8 = rotate(Int8(92), Int8(4)) println("a=${a}") let b: Int32 = rotate(Int32(1), Int8(4)) println("b=${b}") }

运行结果:

a=-59 b=16
  • rotate(Int8(92), 4):92的二进制为0101 1100(8 位),左旋 4 位后各半字节互换得到1100 0101。由于最高位为 1,按有符号Int8解释该二进制补码即为-59;
  • rotate(Int32(1), 4):1左旋 4 位后,最低位的 1 被移到第 4 位,得到2^4 = 16。

第二个用例印证了rotate与<<的区别:若用普通左移1 << 4同样得到16,但当移位数超过位宽时(例如Int8类型旋转 8 位应回到原值),rotate会循环回卷,而普通移位会直接丢弃。

六、完整示例程序与运行结果

以下为 math_basic_operation.md 中给出的完整可运行程序,将四个函数汇总于一个main()中,便于整体验证:

import std.math.clamp import std.math.gcd import std.math.lcm import std.math.rotate // 范围截断示例 func clampTest() { let min: Float16 = -0.123 let max: Float16 = 0.123 let v: Float16 = 0.121 let c = clamp(v, min, max) println("${c==v}") let min2: Float16 = -0.999 let max2: Float16 = 10.123 let v2: Float16 = 11.121 let c2 = clamp(v2, min2, max2) println("${c2==max2}") let min3: Float16 = -0.999 let max3: Float16 = 10.123 let v3: Float16 = -1.121 let c3 = clamp(v3, min3, max3) println("${c3==min3}") } // 求两个数的最大公约数 func gcdTest() { let c2 = gcd(0, -60) println("c2=${c2}") let c4 = gcd(-33, 27) println("c4=${c4}") } // 求两个数的最小公倍数 func lcmTest() { let a: Int8 = lcm(Int8(-3), Int8(5)) println("a=${a}") } // 整数按二进制某一位前后翻转 func rotateTest() { let a: Int8 = rotate(Int8(92), Int8(4)) println("a=${a}") let b: Int32 = rotate(Int32(1), Int8(4)) println("b=${b}") } main(): Unit { println("/*********************** clampTest **********************/") clampTest() println("/*********************** gcdTest ************************/") gcdTest() println("/*********************** lcmTest ************************/") lcmTest() println("/*********************** rotateTest *********************/") rotateTest() }

运行结果:

/*********************** clampTest **********************/ true true true /*********************** gcdTest ************************/ c2=60 c4=3 /*********************** lcmTest ************************/ a=15 /*********************** rotateTest *********************/ a=-59 b=16

七、实战要点与边界总结

综合 math_package_funcs.md 的 API 约束,归纳四个函数的调用要点:

  1. 导入粒度:四个函数分别位于独立的子模块中,需按import std.math.xxx逐函数导入;
  2. clamp 的 NaN 语义:v为NaN时静默返回NaN,而min/max为NaN或min > max时抛IllegalArgumentException,写防御性代码时应先校验区间合法性;
  3. gcd 的溢出边界:两参数同为最小值、或最小值和 0 组合时会抛异常,因为内部取绝对值会溢出;
  4. lcm 的溢出边界:结果超过类型最大值即抛异常;入参含 0 时返回 0,其余情况返回最小的非负公倍数,入参符号不影响结果;
  5. rotate 的方向约定:正数左旋、负数右旋,循环回卷不丢位;有符号类型旋转后可能得到负数(高位为 1 时按补码解释),跨类型使用时(如Int32(1)配合Int8(4))注意位宽与类型匹配。

相关 API 延伸

这四个函数属于 math_package_overview.md 所列能力中的“常用位运算”与“最大公约数与最小公倍数”两组。若需要进一步了解整数/浮点类型的通用能力,可查阅 math_package_interfaces.md 中的Integer<T>接口(提供%、&、|、^、>>、<<等运算符约定)与Number<T>接口;若需要精细控制舍入行为,可参考 math_package_enums.md 中的RoundingMode枚举(包含 IEEE 754 约定的 5 种规则及常用的四舍五入HalfUp)。位运算家族中还提供reverse(按位反转)、countOnes、leadingZeros、trailingZeros等函数,与rotate配合可完成各种位级变换需求。

  • 文档
  • 知识库
  • 教程
  • OpenHarmony

【免费下载链接】CangjieCorpus

本仓库为仓颉编程语言语料库,聚焦 仓颉编程语言 核心知识体系,整合官方开发指南、API 文档、典型代码示例及语法规范等多维度资源,经结构化处理与专业标注,构建为支持 RAG(检索增强生成)技术 的高质量知识基座,适配智能编码助手、学习辅助工具等应用开发需求。 欢迎开发者基于本语料库构建仓颉语言智能应用,推动鸿蒙开发生态智能化升级!

项目地址:https://gitcode.com/Cangjie/CangjieCorpus
点击查看免费下载

相关推荐

上一篇:Salt 的 solaris_shadow 执行模块:在 Solaris 上管理密码数据库的完整指南
下一篇:Yii 2 页面缓存实战:基于 PageCache 过滤器的整页服务端缓存指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询