feat: 完善日月食与月掩几何链路并扩展历法接口
- 新增日月食中心带、偏食带、阴影足迹、等时线、食分线及升落边界计算,支持极区与混合食拓扑 - 新增日食单时刻阴影求解器、站心状态查询、批量采样和 ΔT 覆盖接口 - 重构恒星与行星月掩路径,补充有限盘面接触、站心修正、掩带宽度、极区投影及升落边界 - 扩展 SVG 与 GeoJSON 输出,支持详细面板、全球/极区/地球投影、边界闭合、时间标记和拓扑签名 - 扩展日月食候选搜索、局地搜索、沙罗序列预计算与范围外推,补充系列锚点和成员一致性校验 - 补齐古历纪年、儒略历独有闰日、多公历候选、历法改革跨日及精确日期运算接口 - 优化 ΔT、章动、恒星时、月球地平线、事件根搜索和本地星历缓存,降低重复计算开销并提升边界稳定
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
package basic
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// 记忆表必须逐位精确:命中返回值与重新展开 77 项级数完全一致,且相邻 1 ULP 的输入互不干扰。
|
||||
// The memo must be bit-exact: a hit returns exactly what the 77-term series would recompute, and
|
||||
// inputs one ULP apart keep independent entries.
|
||||
func TestNutationMemoIsBitExact(t *testing.T) {
|
||||
values := []float64{
|
||||
2451545.0, 2460310.5, 0, -1000000.5, -4713.5, 5373484.5,
|
||||
math.NaN(), math.Inf(1), math.Inf(-1), math.SmallestNonzeroFloat64,
|
||||
}
|
||||
for index := 0; index < 5000; index++ {
|
||||
values = append(values, 1000000.0+float64(index)*0.37)
|
||||
}
|
||||
for _, jd := range values {
|
||||
memoPsi, memoEps := Nutation2000B(jd)
|
||||
directPsi, directEps := nutation2000BCompute(jd)
|
||||
if math.Float64bits(memoPsi) != math.Float64bits(directPsi) ||
|
||||
math.Float64bits(memoEps) != math.Float64bits(directEps) {
|
||||
t.Fatalf("jd=%v: memo (%v,%v) != direct (%v,%v)", jd, memoPsi, memoEps, directPsi, directEps)
|
||||
}
|
||||
againPsi, againEps := Nutation2000B(jd)
|
||||
if math.Float64bits(againPsi) != math.Float64bits(memoPsi) ||
|
||||
math.Float64bits(againEps) != math.Float64bits(memoEps) {
|
||||
t.Fatalf("jd=%v: repeated call changed the value", jd)
|
||||
}
|
||||
// 相邻 1 ULP 的输入必须各自独立(不能被同一槽位合并)。
|
||||
neighbour := math.Nextafter(jd, math.Inf(1))
|
||||
if math.IsNaN(jd) || math.IsInf(jd, 0) {
|
||||
continue
|
||||
}
|
||||
nearPsi, _ := Nutation2000B(neighbour)
|
||||
nearDirect, _ := nutation2000BCompute(neighbour)
|
||||
if math.Float64bits(nearPsi) != math.Float64bits(nearDirect) {
|
||||
t.Fatalf("jd=%v neighbour: memo (%v) != direct (%v)", jd, nearPsi, nearDirect)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 章动只依赖传入的 jd:ΔT 覆盖不改变它,因此记忆表不需要世代戳(与视恒星时不同)。
|
||||
func TestNutationMemoIgnoresDeltaTGeneration(t *testing.T) {
|
||||
original := GetDeltaTFn()
|
||||
defer SetDeltaTFn(original)
|
||||
jd := 2460310.5
|
||||
beforePsi, beforeEps := Nutation2000B(jd)
|
||||
SetDeltaTFn(func(date float64, isJd bool) float64 { return 6000 })
|
||||
afterPsi, afterEps := Nutation2000B(jd)
|
||||
if math.Float64bits(beforePsi) != math.Float64bits(afterPsi) ||
|
||||
math.Float64bits(beforeEps) != math.Float64bits(afterEps) {
|
||||
t.Fatalf("nutation changed with the ΔT generation: (%v,%v) vs (%v,%v)", beforePsi, beforeEps, afterPsi, afterEps)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user