方法定义
public static double tan(double a)
- 功能:计算角度的正切值(三角函数)
- 参数:
double
类型弧度值(角度需先转为弧度) - 返回:参数的正切值(
double
类型)
功能说明
标准计算:
Math.tan(0)
= 0.0Math.tan(Math.PI/4)
≈ 1.0Math.tan(Math.PI/3)
≈ 1.732(√3)
特殊值处理: | 输入 | 返回值 | |------------------------|-----------------| |
NaN
|NaN
| | ±0.0 | ±0.0(同号) | | ±∞ |NaN
| | 接近 π/2 + kπ 的奇点 | 极大值或NaN
|数学等价:
tan(x) = sin(x) / cos(x)
示例代码
public class TanExample {
public static void main(String[] args) {
// 基础计算
System.out.println(Math.tan(0)); // 0.0
System.out.println(Math.tan(Math.PI / 4)); // ≈1.0
System.out.println(Math.tan(Math.PI / 3)); // ≈1.732
// 特殊值
System.out.println(Math.tan(Double.NaN)); // NaN
System.out.println(Math.tan(Double.POSITIVE_INFINITY)); // NaN
// 角度转弧度计算
double degrees = 45;
double radians = Math.toRadians(degrees);
System.out.println(Math.tan(radians)); // ≈1.0
// 实际应用:计算物体斜面下滑力
double gravity = 9.8;
double mass = 10;
double angle = 30; // 坡度角度
double force = mass * gravity * Math.tan(Math.toRadians(angle));
System.out.printf("下滑力: %.2f N%n", force); // ≈56.59 N
// 图形学:计算纹理映射偏移
double lightAngle = Math.PI / 3;
double offset = Math.tan(lightAngle) * surfaceDepth;
}
}
使用技巧
角度转弧度
// 使用 Math.toRadians() 转换 double tan30 = Math.tan(Math.toRadians(30));
避免奇点区域
// 检查是否接近 π/2 + kπ boolean isSingularity(double rad) { double normalized = Math.abs(rad % Math.PI); return Math.abs(normalized - Math.PI/2) < 1e-10; }
周期性处理
// 利用 tan(x + π) = tan(x) 减少计算范围 double safeTan(double x) { x = x % Math.PI; // 归约到 [-π, π] return Math.tan(x); }
与反函数结合
// 验证 tan(atan(x)) = x double x = 0.5; double result = Math.tan(Math.atan(x)); // ≈0.5
常见错误与注意事项
混淆角度和弧度
// 错误:直接使用角度值 double wrong = Math.tan(45); // 实际计算45弧度≈1.619(非1.0) // 正确:先转换 double correct = Math.tan(Math.toRadians(45));
奇点未处理
// 错误:接近π/2时结果不可靠 double dangerous = Math.tan(Math.PI/2 - 1e-15); // 返回极大值(可能溢出)
精度问题
// 大数值精度损失 double badPrecision = Math.tan(100000 * Math.PI); // 误差显著增大
数学误解
// 错误:认为tan(90°)=0(实际无定义) double undefined = Math.tan(Math.toRadians(90)); // 返回极大值或NaN
最佳实践与性能优化
小角度优化(泰勒展开)
double fastTanSmall(double x) { if (Math.abs(x) < 0.1) { return x + (x*x*x)/3 + (2*x*x*x*x*x)/15; } return Math.tan(x); }
查表法优化
// 预计算常用角度值(0°-90°) double[] tanTable = new double[91]; for (int deg = 0; deg <= 90; deg++) { tanTable[deg] = Math.tan(Math.toRadians(deg)); } // 使用时直接查表 double tanValue = tanTable[angle];
周期性归约
double optimizedTan(double x) { // 归约到 [-π/2, π/2] x = x % (2 * Math.PI); if (x > Math.PI) x -= 2 * Math.PI; if (x < -Math.PI) x += 2 * Math.PI; if (x > Math.PI/2) return -Math.tan(x - Math.PI); if (x < -Math.PI/2) return -Math.tan(x + Math.PI); return Math.tan(x); }
替代方案性能对比 | 方法 | 耗时(纳秒/调用) | 适用场景 | |---------------------|-----------------|---------------------| |
Math.tan()
| 20-100 ns | 通用场景 | | 泰勒展开(小角度) | 5-20 ns | |x| < 0.1 rad | | 查表法 | 1-5 ns | 固定角度集 | |StrictMath.tan()
| 50-200 ns | 跨平台一致性要求 |
总结
关键点 | 说明 |
---|---|
核心功能 | 计算弧度的正切值 |
参数单位 | 必须使用弧度制(角度需用Math.toRadians() 转换) |
奇点问题 | π/2 + kπ 处无定义(返回极大值或NaN) |
精度范围 | 最大误差 ≤ 1 ulp(但在大输入值时精度下降) |
性能 | 典型调用约20-100纳秒(现代JVM使用硬件加速) |
最佳实践 | 角度转弧度、奇点检查、小角度用泰勒展开、高频调用用查表法 |
替代方案 | StrictMath.tan() (跨平台一致)、查表法(有限角度) |