Skip to content

Instantly share code, notes, and snippets.

@porglezomp
Created July 19, 2018 00:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save porglezomp/3ec824f07d15ba5383992f573e6be120 to your computer and use it in GitHub Desktop.
Save porglezomp/3ec824f07d15ba5383992f573e6be120 to your computer and use it in GitHub Desktop.
Sin/Cos error ULPs
//
// Sin functions
//
const S1: f64 = -0.166666666416265235595; /* -0x15555554cbac77.0p-55 */
const S2: f64 = 0.0083333293858894631756; /* 0x111110896efbb2.0p-59 */
const S3: f64 = -0.000198393348360966317347; /* -0x1a00f9e2cae774.0p-65 */
const S4: f64 = 0.0000027183114939898219064; /* 0x16cd878c3b46a7.0p-71 */
pub fn k_sinf(x: f64) -> f32 {
let z = x * x;
let w = z * z;
let r = S3 + z * S4;
let s = z * x;
((x + s * (S1 + z * S2)) + s * w * r) as f32
}
const S1_F32: f32 = -0.166666666416265235595; /* -0x15555554cbac77.0p-55 */
const S2_F32: f32 = 0.0083333293858894631756; /* 0x111110896efbb2.0p-59 */
const S3_F32: f32 = -0.000198393348360966317347; /* -0x1a00f9e2cae774.0p-65 */
const S4_F32: f32 = 0.0000027183114939898219064; /* 0x16cd878c3b46a7.0p-71 */
fn k_sinf_f32(x: f32) -> f32 {
let z = x * x;
let w = z * z;
let r = S3_F32 + z * S4_F32;
let s = z * x;
((x + s * (S1_F32 + z * S2_F32)) + s * w * r)
}
// Cos functinos
const C0: f64 = -0.499999997251031003120; /* -0x1ffffffd0c5e81.0p-54 */
const C1: f64 = 0.0416666233237390631894; /* 0x155553e1053a42.0p-57 */
const C2: f64 = -0.00138867637746099294692; /* -0x16c087e80f1e27.0p-62 */
const C3: f64 = 0.0000243904487962774090654; /* 0x199342e0ee5069.0p-68 */
pub fn k_cosf(x: f64) -> f32 {
let z = x * x;
let w = z * z;
let r = C2 + z * C3;
(((1.0 + z * C0) + w * C1) + (w * z) * r) as f32
}
const C0_F32: f32 = -0.499999997251031003120; /* -0x1ffffffd0c5e81.0p-54 */
const C1_F32: f32 = 0.0416666233237390631894; /* 0x155553e1053a42.0p-57 */
const C2_F32: f32 = -0.00138867637746099294692; /* -0x16c087e80f1e27.0p-62 */
const C3_F32: f32 = 0.0000243904487962774090654; /* 0x199342e0ee5069.0p-68 */
pub fn k_cosf_f32(x: f32) -> f32 {
let z = x * x;
let w = z * z;
let r = C2_F32 + z * C3_F32;
(((1.0 + z * C0_F32) + w * C1_F32) + (w * z) * r) as f32
}
use std::f32::consts::PI;
fn main() {
let mut sin_err = 0;
let mut cos_err = 0;
for n in 0..=f32::to_bits(PI / 4.0) {
let input = f32::from_bits(n);
sin_err = sin_err.max({
let high_prec_sin = k_sinf(input as f64);
let low_prec_sin = k_sinf_f32(input);
(f32::to_bits(high_prec_sin) as i32)
.wrapping_sub(f32::to_bits(low_prec_sin) as i32)
.abs() as u32
}).max({
let high_prec_sin = k_sinf(-input as f64);
let low_prec_sin = k_sinf_f32(-input);
(f32::to_bits(high_prec_sin) as i32)
.wrapping_sub(f32::to_bits(low_prec_sin) as i32)
.abs() as u32
});
cos_err = cos_err.max({
let high_prec_cos = k_cosf(input as f64);
let low_prec_cos = k_cosf_f32(input);
(f32::to_bits(high_prec_cos) as i32)
.wrapping_sub(f32::to_bits(low_prec_cos) as i32)
.abs() as u32
}).max({
let high_prec_cos = k_cosf(-input as f64);
let low_prec_cos = k_cosf_f32(-input);
(f32::to_bits(high_prec_cos) as i32)
.wrapping_sub(f32::to_bits(low_prec_cos) as i32)
.abs() as u32
});
}
println!("Sin error (ULPs): {}", sin_err);
println!("Cos error (ULPs): {}", cos_err);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment