最稳妥的方法是用平方比较而非sqrt:若(x - cx)² + (y - cy)² ≤ r²,则点在圆内(含边界),避免sqrt开销和浮点误差。

用 sqrt 和平方比较判断点在圆内最稳妥
直接算欧几里得距离再和半径比,看似直观,但 sqrt 开销大,还可能引入浮点误差。更推荐只比平方:若点 (x, y) 到圆心 (cx, cy) 的横纵坐标差的平方和 ≤ 半径 r 的平方,则点在圆内(含边界)。
实操建议:
- 写成
(x - cx) * (x - cx) + (y - cy) * (y - cy) ,避免调用sqrt - 所有变量用
double或float,别混用int和浮点——整数溢出或隐式转换会悄悄出错 - 如果圆心或点坐标来自用户输入或传感器,先检查是否为
NaN或无穷大,否则比较结果未定义
std::hypot 能防溢出但不必要用于圆内判断
std::hypot(x, y) 计算 sqrt(x² + y²) 时内部做了缩放,能避免中间结果溢出。但它本意是处理极端数量级的向量模长,对常规圆内判断属于“杀鸡用牛刀”。
使用场景有限:
立即学习“C++免费学习笔记(深入)”;
- 仅当你的坐标值可能达到
1e150这种量级(远超典型图形/物理模拟范围)才需考虑 - 它比直接平方和慢 3–5 倍,且仍要再和
r比较,不如直接比平方 - 若真要用,也得写成
std::hypot(x - cx, y - cy) ,别漏掉圆心偏移
整数坐标下用纯整数运算完全可行
如果圆心、点、半径全是整数,且你确定不会溢出(比如坐标范围在 ±10⁴ 内),可全程用 int 避免任何浮点问题。
注意点:
- 半径平方用
long long存,防止int r = 50000时r * r溢出 - 坐标差也先转成
long long再平方:auto dx = (long long)(x - cx); dx * dx - 别写
(x - cx) * (x - cx)—— 两个int相乘仍按int算,溢出后截断再赋给long long就晚了
边界情况:点在圆上、圆半径为 0、负半径
数学上圆半径非负,但代码里容易传入负值。C++ 不会自动报错,结果却不可靠。
建议防御性写法:
- 函数开头加断言:
assert(r >= 0)或返回false(若半径 - 半径为 0 时,只有严格等于圆心的点才算“在圆内”,即
x == cx && y == cy - 用
而不是包含圆上点;若业务要求“严格内部”,才改用
浮点比较本身有精度陷阱,但圆内判断用平方和避开了开方,已是实践中最轻量又鲁棒的做法。真正容易被忽略的是整数溢出路径和负半径输入——它们不会崩溃,但会让逻辑在静默中失效。










