mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 16:21:33 +11:00
Fix cos term (#498)
One of the finer cosine terms was not correct. By using the num macro (not available at the time of this functions initial writing) we can avoid issues of incorrect constants. Fixes #497 - [x] Changelog updated
This commit is contained in:
commit
cd6e8d1346
|
@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed inaccuracy in cosine implementation caused by accidentally multiplying correction term by zero.
|
||||||
|
|
||||||
## [0.17.1] - 2023/10/05
|
## [0.17.1] - 2023/10/05
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
@ -133,7 +133,7 @@ macro_rules! upcast_multiply_impl {
|
||||||
.wrapping_mul(b_frac)
|
.wrapping_mul(b_frac)
|
||||||
.wrapping_add(b_floor.wrapping_mul(a_frac)),
|
.wrapping_add(b_floor.wrapping_mul(a_frac)),
|
||||||
)
|
)
|
||||||
.wrapping_add(a_frac.wrapping_mul(b_frac) >> n)
|
.wrapping_add(((a_frac as u32).wrapping_mul(b_frac as u32) >> n) as $T)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
($T: ty, $Upcast: ty) => {
|
($T: ty, $Upcast: ty) => {
|
||||||
|
@ -533,17 +533,10 @@ impl<I: FixedWidthSignedInteger, const N: usize> Num<I, N> {
|
||||||
/// ```
|
/// ```
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn cos(self) -> Self {
|
pub fn cos(self) -> Self {
|
||||||
let one: Self = I::one().into();
|
|
||||||
let mut x = self;
|
let mut x = self;
|
||||||
let four: I = 4.into();
|
x -= num!(0.25) + (x + num!(0.25)).floor();
|
||||||
let two: I = 2.into();
|
x *= (x.abs() - num!(0.5)) * num!(16.);
|
||||||
let sixteen: I = 16.into();
|
x += x * (x.abs() - num!(1.)) * num!(0.225);
|
||||||
let nine: I = 9.into();
|
|
||||||
let forty: I = 40.into();
|
|
||||||
|
|
||||||
x -= one / four + (x + one / four).floor();
|
|
||||||
x *= (x.abs() - one / two) * sixteen;
|
|
||||||
x += x * (x.abs() - one) * (nine / forty);
|
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1234,6 +1227,26 @@ mod tests {
|
||||||
test_base::<11>();
|
test_base::<11>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_cos_accuracy() {
|
||||||
|
let n: Num<i32, 8> = Num::new(1) / 32;
|
||||||
|
assert_eq!(
|
||||||
|
n.cos(),
|
||||||
|
Num::from_f64((2. * core::f64::consts::PI / 32.).cos())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_16_bit_precision_i32() {
|
||||||
|
let a: Num<i32, 16> = num!(1.923);
|
||||||
|
let b = num!(2.723);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
a * b,
|
||||||
|
Num::from_raw(((a.to_raw() as i64 * b.to_raw() as i64) >> 16) as i32)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_numbers() {
|
fn test_numbers() {
|
||||||
// test addition
|
// test addition
|
||||||
|
|
Loading…
Reference in a new issue