关于MyComplex类equalsApprox方法及容差含义的技术咨询
public String toString() { final String IMAGINARY_UNIT = "i"; if (equalsApprox(im , 0)) { return String.valueOf(re); } String sign = "-"; if (im > 0) { sign = "+"; } if(equalsApprox(re, 0)) { return "MyComplex" + sign + IMAGINARY_UNIT + Math.abs(im); } return "MyComplex" + re + " " + sign + IMAGINARY_UNIT + Math.abs(im); } public boolean equalsApprox(MyComplex z) { return equalsApprox(re, z.re) && equalsApprox(im, z.im); } private static boolean equalsApprox(double x , double y) { final double EPSILON = 1E-14; return Math.abs(x-y) <= EPSILON * Math.max(Math.abs(x), Math.abs(y)); }
MyComplex类equalsApprox方法详解
一、容差(Tolerance)的含义
这里的EPSILON = 1E-14是相对容差,它不是固定的误差数值,而是和被比较数值的量级绑定的允许误差比例。简单来说:允许两个数的差异,不超过其中绝对值较大数的10^-14倍。
这种相对容差比固定的绝对容差(比如直接判断|x-y| < 1e-14)更合理——比如比较极小值1e-15和0时,绝对容差会误判为相等,但相对容差能准确识别差异;比较极大值1e15和1e15+1时,绝对容差会认为不等,但相对容差会判断为近似相等(因为差异占比远小于1e-14)。
二、近似比较的实现逻辑
核心逻辑在最底层的静态方法equalsApprox(double x, double y)里,步骤如下:
- 计算两个数的绝对差值:
Math.abs(x-y) - 取两个数中绝对值更大的那个:
Math.max(Math.abs(x), Math.abs(y)) - 用这个最大值乘以容差
EPSILON,得到允许的最大误差范围 - 若绝对差值≤允许误差,返回
true(认为近似相等),否则返回false
举两个实际例子:
- 例1:x=1000,y=1000.000000000001,最大绝对值是1000,允许误差=1000×1e-14=1e-11,绝对差是1e-12 ≤1e-11,返回
true - 例2:x=1e-15,y=0,最大绝对值是1e-15,允许误差=1e-15×1e-14=1e-29,绝对差是1e-15 >1e-29,返回
false
三、各equalsApprox方法的返回逻辑
1. 两个double值的比较
private static boolean equalsApprox(double x , double y) { final double EPSILON = 1E-14; return Math.abs(x-y) <= EPSILON * Math.max(Math.abs(x), Math.abs(y)); }
- 当两个double的相对误差在1e-14范围内时返回
true,否则false - 特殊情况:若x和y都是0,
Math.max(0,0)=0,EPSILON×0=0,Math.abs(0-0)=0,返回true,符合预期
2. 两个MyComplex对象的比较
public boolean equalsApprox(MyComplex z) { return equalsApprox(re, z.re) && equalsApprox(im, z.im); }
- 只有当两个复数的实部近似相等且虚部近似相等时,才返回
true - 只要实部或虚部中有一组不满足近似相等,就返回
false
3. toString方法中的调用场景
在toString里,equalsApprox(im, 0)和equalsApprox(re, 0)用来判断实部/虚部是否近似为0:
- 若虚部近似为0,只返回实部的字符串(比如实部是3.14,就返回"3.14")
- 若实部近似为0,只返回虚部的带符号表达式(比如虚部是-2.5,就返回"MyComplex-i2.5")
- 否则返回完整的复数表达式(比如实部1.0、虚部2.0,返回"MyComplex1.0 +i2.0")
内容的提问来源于stack exchange,提问作者Farzan Firoozkhoshkehrood
相关产品推荐
相关产品推荐

