Created
July 16, 2018 13:34
-
-
Save korken89/6a219e0cf87be244009086072816b524 to your computer and use it in GitHub Desktop.
Test sinf and cosf kernels f32 vs f64 with relative
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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 max_error_sin: f32 = 0.0; | |
let mut max_error_cos: f32 = 0.0; | |
let mut max_rel_error_sin: f32 = 0.0; | |
let mut max_rel_error_cos: f32 = 0.0; | |
for n in 0..100000001 { | |
let input = PI / 4.0 / 100000000.0 * n as f32; | |
let high_prec_sin = k_sinf(input as f64); | |
let low_prec_sin = k_sinf_f32(input); | |
let error_sin = (high_prec_sin - low_prec_sin).abs(); | |
let error_rel_sin = ((high_prec_sin - low_prec_sin) / high_prec_sin).abs(); | |
max_error_sin = max_error_sin.max(error_sin); | |
max_rel_error_sin = max_rel_error_sin.max(error_rel_sin); | |
} | |
for n in -100000000..100000001 { | |
let input = PI / 4.0 / 100000000.0 * n as f32; | |
let high_prec_cos = k_cosf(input as f64); | |
let low_prec_cos = k_cosf_f32(input); | |
let error_cos = (high_prec_cos - low_prec_cos).abs(); | |
let error_rel_cos = ((high_prec_cos - low_prec_cos) / high_prec_cos).abs(); | |
max_error_cos = max_error_cos.max(error_cos); | |
max_rel_error_cos = max_rel_error_cos.max(error_rel_cos); | |
//println!("Error for input {} = {}", input, error); | |
} | |
println!("Max error sin = {}", max_error_sin); | |
println!("Max error cos = {}", max_error_cos); | |
println!("Max relative error sin = {}", max_rel_error_sin); | |
println!("Max relative error cos = {}", max_rel_error_cos); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment