apsis-rs/crates/rf/apsis-rf/tests/decibel.rs

102 lines
3.6 KiB
Rust

//! Tests for the decibel scale.
//!
//! 分贝尺度的测试。
use apsis_rf::Decibel;
const TOLERANCE: f64 = 1e-12;
#[test]
fn unity_and_doubling_have_the_expected_readings() {
assert_eq!(Decibel::UNITY.db(), 0.0);
assert!((Decibel::UNITY.ratio() - 1.0).abs() < TOLERANCE);
// Three decibels is a ratio of 1.9953, not exactly two, which is the
// reason the doubling constant is an approximation in practice.
// 三分贝是 1.9953 的比而非恰好二,这正是加倍常量在实践中是近似的原因。
assert!((Decibel::DOUBLING.db() - 3.010_299_956_639_812).abs() < TOLERANCE);
assert!((Decibel::DOUBLING.ratio() - 2.0).abs() < TOLERANCE);
}
#[test]
fn ratio_and_reading_round_trip() {
for reading in [-30.0, -10.0, -3.0, 0.0, 1.5, 10.0, 30.0, 100.0] {
let value = Decibel::from_db(reading);
let ratio = value.ratio();
let recovered = Decibel::from_ratio(ratio).expect("ratio is positive");
assert!((recovered.db() - reading).abs() < 1e-9, "reading {reading}");
}
}
#[test]
fn a_ratio_of_ten_is_ten_decibels() {
assert!((Decibel::from_ratio(10.0).expect("positive").db() - 10.0).abs() < TOLERANCE);
assert!((Decibel::from_ratio(100.0).expect("positive").db() - 20.0).abs() < TOLERANCE);
assert!((Decibel::from_ratio(0.001).expect("positive").db() + 30.0).abs() < TOLERANCE);
}
#[test]
fn amplitude_ratios_use_twenty_per_decade() {
// A voltage ratio of ten is twenty decibels, because power is
// proportional to the square of the amplitude.
// 电压比十即二十分贝,因为功率与幅度的平方成正比。
let value = Decibel::from_amplitude_ratio(10.0).expect("positive");
assert!((value.db() - 20.0).abs() < TOLERANCE);
assert!((value.amplitude_ratio() - 10.0).abs() < 1e-9);
}
#[test]
fn non_positive_ratios_are_rejected() {
assert_eq!(Decibel::from_ratio(0.0), None);
assert_eq!(Decibel::from_ratio(-1.0), None);
assert_eq!(Decibel::from_ratio(f64::NAN), None);
assert_eq!(Decibel::from_ratio(f64::INFINITY), None);
assert_eq!(Decibel::from_amplitude_ratio(0.0), None);
}
#[test]
fn addition_multiplies_the_ratio() {
// The exact doubling constant added to itself quadruples the ratio.
// 精确的加倍常量自加使其比变为四倍。
let total = Decibel::DOUBLING + Decibel::DOUBLING;
assert!((total.ratio() - 4.0).abs() < 1e-9);
// Two ten decibel gains make a gain of one hundred.
// 两个十分贝增益合成一百倍增益。
let decades = Decibel::from_db(10.0) + Decibel::from_db(10.0);
assert!((decades.db() - 20.0).abs() < TOLERANCE);
assert!((decades.ratio() - 100.0).abs() < 1e-9);
}
#[test]
fn subtraction_divides_the_ratio() {
let net = Decibel::from_db(10.0) - Decibel::from_db(3.0);
assert!((net.db() - 7.0).abs() < TOLERANCE);
let ratio = Decibel::from_db(10.0).ratio() / Decibel::from_db(3.0).ratio();
assert!((net.ratio() - ratio).abs() < 1e-9);
}
#[test]
fn negation_inverts_the_ratio() {
let value = Decibel::from_db(7.5);
assert!((-value).db() + value.db() < TOLERANCE);
assert!(((-value).ratio() * value.ratio() - 1.0).abs() < 1e-12);
assert_eq!((-value).db(), value.negated().db());
}
#[test]
fn finiteness_is_reported() {
assert!(Decibel::from_db(1.0).is_finite());
assert!(!Decibel::from_db(f64::INFINITY).is_finite());
assert!(!Decibel::from_db(f64::NAN).is_finite());
}
#[test]
fn display_includes_the_unit() {
assert_eq!(Decibel::from_db(3.5).to_string(), "3.5 dB");
}
#[test]
fn default_is_unity() {
assert_eq!(Decibel::default(), Decibel::UNITY);
}