is_equal_approx
最后同步日期:2026-04-15 | Godot 官方原文 — is_equal_approx
is_equal_approx
定义
is_equal_approx 是一个用来判断两个浮点数是否"近似相等"的函数。
打个比方:假设你有两根绳子,想知道它们是不是"差不多一样长"。如果你拿尺子精确到毫米去量,可能一根是 100.0mm,另一根是 100.00001mm——严格来说它们不一样长,但肉眼根本看不出区别。is_equal_approx 就是那个"肉眼判断"——只要差异小到可以忽略,它就认为两者相等。
用普通的 == 比较浮点数,就像拿着显微镜找差异,一点点微小的精度误差都会导致判断失败。而 is_equal_approx 允许一个极小的误差范围(大约 0.00001),专门用来应对浮点数计算中不可避免的精度丢失问题。
什么时候需要用到它?
- 比较两个浮点数是否相等时(永远不要用
==比较浮点数!) - 判断物体的位置、速度等是否到达目标值
- 验证数学计算结果是否在预期范围内
函数签名
// 静态方法,通过 Mathf 类调用
public static bool IsEqualApprox(float a, float b)# 全局函数,无需前缀直接调用
func is_equal_approx(a: float, b: float) -> bool参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
a | float | 第一个要比较的浮点数 |
b | float | 第二个要比较的浮点数 |
返回值
bool — 如果 a 和 b 的差值在可接受的误差范围内,返回 true;否则返回 false。
具体来说,当满足以下条件时返回 true:
abs(a - b) < 0.00001 * max(abs(a), abs(b))
也就是说,差异越小越容易通过,而且对于越大的数,允许的绝对误差也越大。
代码示例
基本用法:比较浮点数
using Godot;
public partial class MyNode : Node
{
public override void _Ready()
{
float a = 0.1f + 0.2f;
float b = 0.3f;
// 用 == 比较——很可能失败!因为浮点精度问题
// 0.1 + 0.2 在计算机中并不精确等于 0.3
GD.Print(a == b); // 输出: False
// 用 is_equal_approx 比较——正确的方式
GD.Print(Mathf.IsEqualApprox(a, b)); // 输出: True
}
}extends Node
func _ready():
var a = 0.1 + 0.2
var b = 0.3
# 用 == 比较——很可能失败!因为浮点精度问题
# 0.1 + 0.2 在计算机中并不精确等于 0.3
print(a == b) # 输出: False
# 用 is_equal_approx 比较——正确的方式
print(is_equal_approx(a, b)) # 输出: True实际场景:判断物体是否到达目标位置
using Godot;
public partial class MovingPlatform : Node3D
{
// 导出属性:目标位置
[Export] public Vector3 ExTargetPosition = new Vector3(10f, 0f, 0f);
// 导出属性:移动速度
[Export] public float ExSpeed = 2.0f;
// 内部变量:是否正在移动
private bool _isMoving = true;
public override void _Process(double delta)
{
if (!_isMoving) return;
// 向目标位置移动
Position = Position.MoveToward(ExTargetPosition, ExSpeed * (float)delta);
// 用 is_equal_approx 判断是否到达目标(逐个坐标判断)
if (Mathf.IsEqualApprox(Position.X, ExTargetPosition.X)
&& Mathf.IsEqualApprox(Position.Y, ExTargetPosition.Y)
&& Mathf.IsEqualApprox(Position.Z, ExTargetPosition.Z))
{
GD.Print("平台已到达目标位置!");
_isMoving = false;
}
}
}extends Node3D
# 导出属性:目标位置
@export var target_position: Vector3 = Vector3(10.0, 0.0, 0.0)
# 导出属性:移动速度
@export var speed: float = 2.0
# 内部变量:是否正在移动
var _is_moving: bool = true
func _process(delta):
if not _is_moving:
return
# 向目标位置移动
position = position.move_toward(target_position, speed * delta)
# 用 is_equal_approx 判断是否到达目标(逐个坐标判断)
if is_equal_approx(position.x, target_position.x) \
and is_equal_approx(position.y, target_position.y) \
and is_equal_approx(position.z, target_position.z):
print("平台已到达目标位置!")
_is_moving = false注意事项
永远不要用
==比较浮点数:由于计算机存储浮点数的方式,0.1 + 0.2 == 0.3会返回false。请始终使用is_equal_approx或自定义误差范围。误差范围不是固定的:
is_equal_approx使用的是相对误差,也就是说对于很大的数(比如10000.0)允许的误差会更大,对于很小的数(比如0.001)允许的误差会更小。这符合大多数游戏开发的实际需求。如果需要精确控制误差范围:可以使用
abs(a - b) < your_threshold自定义判断逻辑,比如要求误差不超过0.001:# 自定义误差范围 if abs(a - b) < 0.001: print("足够接近了!")Vector2 和 Vector3 有自己的近似相等方法:
Vector2.IsEqualApprox()和Vector3.IsEqualApprox(),它们会对每个分量分别调用is_equal_approx。
