判断坐标象限应优先使用整数版if链并检查坐标轴,浮点场景加abs判断即可;位运算等技巧易误判零值、丧失可读性,仅适用于非零整数且性能极端敏感的特殊场景。

判断坐标象限的核心逻辑是看 x 和 y 的正负组合
在标准笛卡尔坐标系中,象限由 x 和 y 的符号唯一决定:第一象限(x > 0 && y > 0),第二象限(x 0),第三象限(x ),第四象限(<code>x > 0 && y )。原点(<code>x == 0 && y == 0)和坐标轴上点(任一为 0)不属于任何象限,必须单独处理。
用 if-else 链处理边界情况最稳妥
直接用嵌套 if 或并列 else if 判断,避免漏掉坐标轴上的点。常见错误是只写四个分支,结果把 (5, 0) 或 (0, -3) 错判为第四或第三象限。
推荐写法:
int quadrant(int x, int y) {
if (x == 0 || y == 0) return 0; // 0 表示不在象限内
if (x > 0 && y > 0) return 1;
if (x < 0 && y > 0) return 2;
if (x < 0 && y < 0) return 3;
return 4; // 此时必为 x > 0 && y < 0
}-
return 0是约定俗成的“无效象限”标识,比抛异常或返回 -1 更轻量 - 浮点坐标需改用
std::abs(x) 判断是否在轴上,<code>EPS建议设为1e-9 - 不要用
signbit()或位运算替代比较——可读性差,且对0.0和-0.0处理不一致
switch + 编码技巧只适合整数且无轴上需求的场景
有人用 (x > 0 ? 1 : 0) * 2 + (y > 0 ? 1 : 0) 得到 0~3 映射再 switch,看似简洁,但会把 (0, 5) 算成 1(误判为第一象限),且丧失可读性。这种技巧仅在明确保证输入非零整数、且性能极端敏感(如图形管线内循环)时才考虑。
立即学习“C++免费学习笔记(深入)”;
- 编码值
0对应x≤0, y≤0,不是第三象限 - 无法区分
(0, -2)和(-1, -2) - 一旦加浮点支持,整个逻辑立刻失效
注意浮点比较和 -0.0 的陷阱
用 double 时,y == 0.0 可能因精度失败;而 -0.0 == 0.0 为真,但 std::signbit(-0.0) 返回 true。若业务要求严格区分正负零(极少见),必须用 std::signbit 配合 !std::isnormal 检查。
- 日常判断象限,用
std::abs(y) 足够安全 - 别依赖
static_cast<int>(std::copysign(1.0, x))</int>——它对-0.0返回 -1,但0.0和-0.0在几何意义上等价 - 如果输入来自传感器或文件解析,先做一次
std::frexp校验是否为 NaN,否则NaN > 0结果为false,可能意外落入第四象限分支
实际用的时候,绝大多数情况只需整数版 if 链加一个轴上检查——复杂度低、易调试、边界清晰。浮点场景下多一行 abs 判断,远比折腾位运算或模板元编程实在。


















