尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
yq 取模运算符(%)完全指南:整数、浮点数与除零行为深度解析
yq 取模运算符%完全指南整数、浮点数与除零行为深度解析【免费下载链接】yqyq is a portable command-line YAML, JSON, XML, CSV, TOML, HCL and properties processor项目地址: https://gitcode.com/GitHub_Trending/yq/yq导读本文围绕 yqportable command-line YAML/JSON/XML/CSV/TOML/HCL/properties 处理器的算术取模运算符%展开系统讲解其在整数、浮点数场景下的计算规则以及除零时的错误与 NaN 行为并深入 pkg/yqlib/operator_modulo.go 源码剖析底层实现。读完本文你将掌握 yq 中%运算符的完整语义、类型判定逻辑与边界行为能够在数据处理管道中正确使用取模运算。运算符概述返回两数相除的余数取模Modulo是 yq 算术运算家族中的二元运算符语法形式为lhs % rhs其语义为返回左侧操作数除以右侧操作数后所得的余数。官方定义文档位于 pkg/yqlib/doc/operators/modulo.md。从源码角度看%运算符在 pkg/yqlib/operation.go 中被注册为二元操作节点var moduloOpType operationType{Type: MODULO, NumArgs: 2, Precedence: 42, Handler: moduloOperator}NumArgs: 2表示它是二元运算符需要左右两个操作数Precedence: 42与乘法*、除法/相同的优先级见同文件的multiplyOpType、divideOpType因此在复合表达式中%会先于加减号求值词法层面%符号在 pkg/yqlib/lexer_participle.go 中被识别为moduloOpType操作符 token。整数取模两侧均为 int 时按整数计算当左侧lhs与右侧rhs操作数都是整数YAML 标签!!int时yq 使用整数运算完成取模结果同样为整数。给定sample.ymla: 13 b: 2执行yq .a .a % .b sample.yml输出a: 1 b: 2即13 % 2 1其中.a .a % .b是「先计算.a % .b再把结果赋回.a」的复合赋值写法。底层实现parseInt64 与格式保真整数取模路径位于 pkg/yqlib/operator_modulo.go 的moduloScalars函数当lhsTag !!int rhsTag !!int时先通过parseInt64解析两个操作数的值检测到rhsNum 0则直接报错否则计算lhsNum % rhsNum并写回结果。值得注意的细节是yq 在解析整数时并非简单调用strconv.ParseInt而是经由 pkg/yqlib/lib.go 的parseInt64做了特殊处理自动去除数字中的下划线如1_000支持十六进制0x/0X前缀按 16 进制解析并保留0x%X输出格式支持八进制0o前缀按 8 进制解析并保留0o%o输出格式其余情况按十进制解析。这意味着yq .a .a % .b也能正确处理诸如0xF、0o10、1_000这类符合 YAML 规范的整数写法并且结果会保留左侧操作数原有的数值进制格式target.Value fmt.Sprintf(format, remainder)format来自parseInt64的返回值。浮点取模任一侧为 float 时按浮点计算当左侧或右侧操作数中任一方是浮点数!!float时yq 切换到浮点运算使用 Go 标准库的math.Mod计算余数结果始终为浮点数。给定sample.ymla: 12 b: 2.5执行yq .a .a % .b sample.yml输出a: 2 b: 2.5即12 % 2.5 212 2.5 × 4 2余数为 2.0。底层实现math.Mod 与标签重写对应的实现位于 pkg/yqlib/operator_modulo.go当lhsTag与rhsTag属于{!!int, !!float}集合时两侧都会被strconv.ParseFloat(value, 64)解析为 float64然后执行remainder : math.Mod(lhsNum, rhsNum) target.Value fmt.Sprintf(%v, remainder)此时结果的 YAML 标签会被统一重写为!!float除非左侧是自定义标签即使右侧是整数、左侧是整数 右侧是浮点的混合组合也按此规则处理。上述浮点分支同样覆盖「左侧整数、右侧浮点」与「左侧浮点、右侧整数」两种混合情形测试用例见 pkg/yqlib/operator_modulo_test.go。除零行为整数报错浮点得 NaN除零是取模运算最典型的边界场景yq 对整数与浮点给出了两种截然不同的处理结果。整数除以零直接报错如果左侧是整数、右侧为0yq 会中止计算并抛出错误。给定sample.ymla: 1 b: 0执行yq .a .a % .b sample.yml输出Error: cannot modulo by 0该错误信息来自 pkg/yqlib/operator_modulo.go 中对rhsNum 0的显式检查if rhsNum 0 { return fmt.Errorf(cannot modulo by 0) }这是因为 Go 语言中整数取模遇到除数为 0 会触发运行时 panicyq 因此必须在计算前主动拦截并转为可读错误。对应测试用例见 pkg/yqlib/operator_modulo_test.go通过expectedError: cannot modulo by 0校验。浮点除以零返回 NaN如果左侧是浮点数、右侧为0yq 不会报错而是返回NaNNot a Number。给定sample.ymla: 1.1 b: 0执行yq .a .a % .b sample.yml输出a: NaN b: 0其原因是浮点分支调用的math.Mod(1.1, 0)在 Go 标准库中天然返回NaNyq 直接将该值序列化输出。测试用例见 pkg/yqlib/operator_modulo_test.go期望结果为{a: NaN, b: 0}。注意整数除零报错、浮点除零得 NaN 的差异源于 IEEE 754 浮点标准与整数算术语义的根本区别这在数据处理脚本中可能导致「看起来相同、行为不同」的陷阱需要结合操作数的 YAML 标签!!int/!!float仔细甄别。操作数求值机制crossFunction 交叉求值%运算符本身只是一个二元「计算函数」真正驱动它工作的是 pkg/yqlib/operators.go 中的crossFunction交叉求值框架func moduloOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) { log.Debugf(Modulo operator) return crossFunction(d, context.ReadOnlyClone(), expressionNode, modulo, false) }crossFunction会先对右侧表达式求值得到一组候选节点再与左侧的每个候选节点逐一配对调用modulo计算函数即笛卡尔积式求值。例如.a .a % .b这类复合赋值最终会翻译为「先取.a与.b的值做取模再执行赋值」的组合操作复合赋值机制见 pkg/yqlib/operators.go 的compoundAssignFunction。真正的计算函数modulopkg/yqlib/operator_modulo.go还承担了类型前置校验左侧为!!null时直接报错cannot modulo by两侧必须都是标量节点ScalarNode否则报错只有通过校验的标量才会进入moduloScalars做实际的类型分派计算。类型不匹配与扩展场景从测试看边界除了文档中记载的四种常规场景pkg/yqlib/operator_modulo_test.go 还覆盖了大量边界与扩展用例可作为实战参考1非数值类型一律报错。字符串、映射、序列等非数值类型无法参与取模表达式错误信息123 % 2int % str!!int cannot modulo by !!str2 % 123str % int!!str cannot modulo by !!int{a:1} % 2map % int!!map (a) cannot modulo by !!int (b)[1,2] % 2seq % str!!seq (a) cannot modulo by !!str (b)2自定义标签custom tag的数值推断。若操作数带有自定义 YAML 标签如!horse 333.975、!goat 299.2yq 会通过guessTagFromCustomType根据值内容推断其数值类型标签本身非!!开头时走「猜测」分支pkg/yqlib/operator_modulo.go浮点结果会保留左侧的自定义标签a: !horse 333.975 b: !goat 299.2执行.a .a % .b后得到a: !horse 34.775000000000034 b: !goat 299.23保留锚点anchor。取模运算只改写目标节点的值不影响原有锚点结构测试中.a[1] .a[0] % 2对带锚点horse的数组操作后锚点依然保留。4混合运算结果标签。左侧为整数、右侧为自定义浮点标签时结果仍保持整数语义测试a: 2,b: !goat 2.3的.a % .b结果为2。实战建议与小结判断类型再取模由于整数与浮点除零行为完全不同处理可能为 0 的除数时建议先通过kind或 YAML 标签判断操作数类型再决定是捕获错误还是容忍NaN结果善用复合赋值.a .a % .b与%运算符本身等价于「求余后回写」是文档与测试中最常用的写法适合逐字段求余优先级意识%与*、/同级Precedence 42在复杂表达式中注意使用括号明确求值顺序格式保留整数取模会保留左侧操作数的进制格式十六进制、八进制、下划线分隔不会意外丢失 YAML 数值格式信息。综上所述yq 的%取模运算符语义清晰、边界明确整数走parseInt64 原生取模除零报错浮点走math.Mod除零得 NaN非标量与非数值类型一律报错。掌握这些规则即可在 YAML/JSON 数据处理脚本中安全、精确地运用取模运算。【免费下载链接】yqyq is a portable command-line YAML, JSON, XML, CSV, TOML, HCL and properties processor项目地址: https://gitcode.com/GitHub_Trending/yq/yq创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

使用 iii SDK 构建跨语言 Worker:Node、Python、Rust、Go 统一开发指南

使用 iii SDK 构建跨语言 Worker:Node、Python、Rust、Go 统一开发指南

使用 iii SDK 构建跨语言 Worker:Node、Python、Rust、Go 统一开发指南 【免费下载链接】iii Effortlessly compose, extend, and observe every service in real-time for the first time ever. 项目地址: https://gitcode.com/GitHub_Trending/mo/iii iii …

📅 2026/9/14 20:48:29
Windows安装Anaconda全流程:下载、环境变量、换源与验证

Windows安装Anaconda全流程:下载、环境变量、换源与验证

装 Anaconda 这件事,我帮身边朋友处理过不下几十次,翻车最多的地方出奇一致:cmd 里敲conda --version,系统冷冰冰回一句“不是内部或外部命令”。剩下的人里,还有一大部分是装完能跑,但每次conda install都…

📅 2026/9/14 20:48:29
JDK Docker 容器测试在 Ubuntu 18.04 失败怎么设置 docker 镜像参数排查?

JDK Docker 容器测试在 Ubuntu 18.04 失败怎么设置 docker 镜像参数排查?

JDK Docker 容器测试在 Ubuntu 18.04 失败怎么设置 docker 镜像参数排查? 【免费下载链接】jdk JDK main-line development https://openjdk.org/projects/jdk 项目地址: https://gitcode.com/GitHub_Trending/jd/jdk 在 OpenJDK 主开发仓库(jdk&…

📅 2026/9/14 20:43:29
MORE NEWS

更多资讯

📰

自媒体矩阵工具实用推荐|实测好用、新手零门槛运营工具

一、行业痛点:手动多平台分发的实际困境多平台内容分发正在成为自媒体运营的标准配置,但工具选择直接决定运营效率。做自媒体的人大概都经历过这样的流程:一条内容拍完剪完写完,真正耗时的不是创作本身,而是往各个平台…

📰

领域驱动设计(DDD)核心实践与微服务协同

1. 领域驱动设计(DDD)的本质与价值领域驱动设计(Domain-Driven Design,简称DDD)不是一套银弹式的技术框架,而是一种应对复杂业务系统的思维方式。2003年Eric Evans首次系统性地提出这套方法论时&#xff0c…

📰

如何在 Megatron-LM 中开启确定性训练并验证位级可复现?

如何在 Megatron-LM 中开启确定性训练并验证位级可复现? 【免费下载链接】Megatron-LM Ongoing research training transformer models at scale 项目地址: https://gitcode.com/GitHub_Trending/me/Megatron-LM 在 Megatron-LM 中训练 Transformer 时&#…

📰

OpenClaw Telegram 端到端验证:用真实用户驱动 basic-turns 证明 DM、群组与原生命令三条消息链路

OpenClaw Telegram 端到端验证:用真实用户驱动 basic-turns 证明 DM、群组与原生命令三条消息链路 【免费下载链接】openclaw The AI that really does things. Any OS. Any Platform. The lobster way. 🦞 项目地址: https://gitcode.com/GitHub_Tre…

📰

Wand-Enhancer 完整指南:三步构建 Wand(WeMod)增强工具并连上手机远程面板

Wand-Enhancer 完整指南:三步构建 Wand(WeMod)增强工具并连上手机远程面板 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/GitHub_Trending/we/Wand-Enh…

📰

杂记(前后端通信)

PathVariable / RequestParam / RequestBody 三者的区别 PathVariable:URL 路径上的变量,REST 风格,放在 / 之间 GET /user/123 RequestParam:URL 问号后面的查询参数 GET /user?namezhangsan&age18 RequestBody&#…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬