fmod
2026/4/15大约 3 分钟
最后同步日期:2026-04-15 | Godot 官方原文 — fmod
fmod
定义
fmod() 用来计算两个浮点数相除的余数——简单说,就是"分完之后还剩多少"。
想象你有 10.5 块蛋糕,要平均分给 3 个人。每人分到 3.5 块(3 × 3.5 = 10.5),刚好分完,余数是 0。如果蛋糕是 10.7 块呢?每人还是 3.5 块,总共用了 10.5 块,剩下 0.2 块。fmod(10.7, 3.5) 就返回 0.2。
fmod 和整数取余(%)的区别在于:fmod 可以处理带小数的数字。但要注意,fmod 在遇到负数时可能返回负数余数(和被除数同号),如果你希望余数始终为正,请使用 fposmod()。
函数签名
C#
// C# 中直接使用 % 运算符即可实现 fmod 效果
float remainder = x % y;GDScript
func fmod(x: float, y: float) -> float参数说明
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
x | float | 是 | 被除数(要分的总数) |
y | float | 是 | 除数(每份的大小),不能为 0 |
返回值
float —— x 除以 y 的余数。结果的符号与 x(被除数)相同。
| 表达式 | 结果 | 说明 |
|---|---|---|
fmod(10.5, 3.0) | 1.5 | 10.5 = 3 × 3 + 1.5 |
fmod(7.5, 2.5) | 0.0 | 刚好整除 |
fmod(-10.5, 3.0) | -1.5 | 余数与被除数同号 |
fmod(10.5, -3.0) | 1.5 | 余数与被除数同号 |
代码示例
C#
// ===== 基础用法 =====
float a = 10.5f % 3.0f;
// 运行结果: a = 1.5(10.5 = 3 × 3 + 1.5)
float b = 7.5f % 2.5f;
// 运行结果: b = 0.0(7.5 刚好被 2.5 整除)
float c = -10.5f % 3.0f;
// 运行结果: c = -1.5(余数与被除数同号)
float d = 10.5f % -3.0f;
// 运行结果: d = 1.5(余数与被除数同号)
// ===== 实际场景:循环动画时间 =====
using Godot;
public partial class AnimationLooper : Node
{
[Export] public float ExAnimLength = 3.5f; // 动画总时长(秒)
public override void _Process(double delta)
{
// 用 Time.GetTicksMsec() 获取运行时间(模拟)
float currentTime = 8.2f;
// 让时间在动画时长内循环
float loopedTime = currentTime % ExAnimLength;
GD.Print($"动画播放位置: {loopedTime:F1}");
// 运行结果: 动画播放位置: 1.2(8.2 = 3.5 × 2 + 1.2,回到第 1.2 秒)
}
}
// ===== 进阶用法:角度归一化(简易版) =====
// 将任意角度归一化到 0~360 范围
public float NormalizeAngle(float angle)
{
float result = angle % 360.0f;
if (result < 0) result += 360.0f; // 处理负数
return result;
}
// 测试:
// NormalizeAngle(370.5f) → 运行结果: 10.5(超过 360,取余后得到 10.5)
// NormalizeAngle(-45.0f) → 运行结果: 315.0(负角度转为等效正角度)
// NormalizeAngle(180.0f) → 运行结果: 180.0(在范围内,不变)
// 注意:更可靠的做法是使用 fposmod(angle, 360.0)GDScript
# ===== 基础用法 =====
var a = fmod(10.5, 3.0)
# 运行结果: a = 1.5(10.5 = 3 × 3 + 1.5)
var b = fmod(7.5, 2.5)
# 运行结果: b = 0.0(7.5 刚好被 2.5 整除)
var c = fmod(-10.5, 3.0)
# 运行结果: c = -1.5(余数与被除数同号)
var d = fmod(10.5, -3.0)
# 运行结果: d = 1.5(余数与被除数同号)
# ===== 实际场景:循环动画时间 =====
extends Node
@export var ex_anim_length: float = 3.5 # 动画总时长(秒)
func _process(_delta):
# 用 Time.get_ticks_msec() 获取运行时间(模拟)
var current_time = 8.2
# 让时间在动画时长内循环
var looped_time = fmod(current_time, ex_anim_length)
print("动画播放位置: %.1f" % looped_time)
# 运行结果: 动画播放位置: 1.2(8.2 = 3.5 × 2 + 1.2,回到第 1.2 秒)
# ===== 进阶用法:角度归一化(简易版) =====
# 将任意角度归一化到 0~360 范围
func normalize_angle(angle: float) -> float:
var result = fmod(angle, 360.0)
if result < 0:
result += 360.0 # 处理负数
return result
# 测试:
# normalize_angle(370.5) → 运行结果: 10.5(超过 360,取余后得到 10.5)
# normalize_angle(-45.0) → 运行结果: 315.0(负角度转为等效正角度)
# normalize_angle(180.0) → 运行结果: 180.0(在范围内,不变)
# 注意:更可靠的做法是使用 fposmod(angle, 360.0)注意事项
- 除数不能为 0:如果
y为 0,会导致除零错误。 - 余数可能为负:
fmod返回的余数符号与被除数x相同。如果你需要余数始终为非负数,请使用fposmod()。 - C# 中
Math.IEEERemainder()的行为与fmod略有不同(它遵循 IEEE 754 标准),大多数情况下直接用%运算符即可。 fmod处理的是浮点数,如果需要对整数取余,直接使用%运算符或posmod()。
