Skip to content

Commit dcd49cc

Browse files
committed
Add Fractional, Real and RealExt traits
1 parent 6fa054d commit dcd49cc

File tree

6 files changed

+724
-71
lines changed

6 files changed

+724
-71
lines changed

src/libcore/core.rc

+1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ pub use iter::{ExtendedMutableIter};
105105

106106
pub use num::{Num, NumCast};
107107
pub use num::{Signed, Unsigned, Integer};
108+
pub use num::{Fractional, Real, RealExt};
108109
pub use ptr::Ptr;
109110
pub use to_str::ToStr;
110111
pub use clone::Clone;

src/libcore/num/f32.rs

+192-19
Original file line numberDiff line numberDiff line change
@@ -327,31 +327,176 @@ impl Signed for f32 {
327327
fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == neg_infinity }
328328
}
329329

330-
impl num::Round for f32 {
331-
#[inline(always)]
332-
fn round(&self, mode: num::RoundMode) -> f32 {
333-
match mode {
334-
num::RoundDown => floor(*self),
335-
num::RoundUp => ceil(*self),
336-
num::RoundToZero if self.is_negative() => ceil(*self),
337-
num::RoundToZero => floor(*self),
338-
num::RoundFromZero if self.is_negative() => floor(*self),
339-
num::RoundFromZero => ceil(*self)
340-
}
341-
}
330+
impl Fractional for f32 {
331+
/// The reciprocal (multiplicative inverse) of the number
332+
#[inline(always)]
333+
fn recip(&self) -> f32 { 1.0 / *self }
334+
}
335+
336+
impl Real for f32 {
337+
/// Archimedes' constant
338+
#[inline(always)]
339+
fn pi() -> f32 { 3.14159265358979323846264338327950288 }
340+
341+
/// 2.0 * pi
342+
#[inline(always)]
343+
fn two_pi() -> f32 { 6.28318530717958647692528676655900576 }
344+
345+
/// pi / 2.0
346+
#[inline(always)]
347+
fn frac_pi_2() -> f32 { 1.57079632679489661923132169163975144 }
348+
349+
/// pi / 3.0
350+
#[inline(always)]
351+
fn frac_pi_3() -> f32 { 1.04719755119659774615421446109316763 }
352+
353+
/// pi / 4.0
354+
#[inline(always)]
355+
fn frac_pi_4() -> f32 { 0.785398163397448309615660845819875721 }
356+
357+
/// pi / 6.0
358+
#[inline(always)]
359+
fn frac_pi_6() -> f32 { 0.52359877559829887307710723054658381 }
360+
361+
/// pi / 8.0
362+
#[inline(always)]
363+
fn frac_pi_8() -> f32 { 0.39269908169872415480783042290993786 }
364+
365+
/// 1 .0/ pi
366+
#[inline(always)]
367+
fn frac_1_pi() -> f32 { 0.318309886183790671537767526745028724 }
368+
369+
/// 2.0 / pi
370+
#[inline(always)]
371+
fn frac_2_pi() -> f32 { 0.636619772367581343075535053490057448 }
372+
373+
/// 2.0 / sqrt(pi)
374+
#[inline(always)]
375+
fn frac_2_sqrtpi() -> f32 { 1.12837916709551257389615890312154517 }
376+
377+
/// sqrt(2.0)
378+
#[inline(always)]
379+
fn sqrt2() -> f32 { 1.41421356237309504880168872420969808 }
380+
381+
/// 1.0 / sqrt(2.0)
382+
#[inline(always)]
383+
fn frac_1_sqrt2() -> f32 { 0.707106781186547524400844362104849039 }
384+
385+
/// Euler's number
386+
#[inline(always)]
387+
fn e() -> f32 { 2.71828182845904523536028747135266250 }
388+
389+
/// log2(e)
390+
#[inline(always)]
391+
fn log2_e() -> f32 { 1.44269504088896340735992468100189214 }
392+
393+
/// log10(e)
394+
#[inline(always)]
395+
fn log10_e() -> f32 { 0.434294481903251827651128918916605082 }
396+
397+
/// log(2.0)
398+
#[inline(always)]
399+
fn log_2() -> f32 { 0.693147180559945309417232121458176568 }
400+
401+
/// log(10.0)
402+
#[inline(always)]
403+
fn log_10() -> f32 { 2.30258509299404568401799145468436421 }
342404

343405
#[inline(always)]
344406
fn floor(&self) -> f32 { floor(*self) }
407+
345408
#[inline(always)]
346409
fn ceil(&self) -> f32 { ceil(*self) }
410+
347411
#[inline(always)]
348-
fn fract(&self) -> f32 {
349-
if self.is_negative() {
350-
(*self) - ceil(*self)
351-
} else {
352-
(*self) - floor(*self)
353-
}
354-
}
412+
fn round(&self) -> f32 { round(*self) }
413+
414+
#[inline(always)]
415+
fn trunc(&self) -> f32 { trunc(*self) }
416+
417+
/// The fractional part of the number, calculated using: `n - floor(n)`
418+
#[inline(always)]
419+
fn fract(&self) -> f32 { *self - self.floor() }
420+
421+
#[inline(always)]
422+
fn pow(&self, n: f32) -> f32 { pow(*self, n) }
423+
424+
#[inline(always)]
425+
fn exp(&self) -> f32 { exp(*self) }
426+
427+
#[inline(always)]
428+
fn exp2(&self) -> f32 { exp2(*self) }
429+
430+
#[inline(always)]
431+
fn expm1(&self) -> f32 { expm1(*self) }
432+
433+
#[inline(always)]
434+
fn ldexp(&self, n: int) -> f32 { ldexp(*self, n as c_int) }
435+
436+
#[inline(always)]
437+
fn log(&self) -> f32 { ln(*self) }
438+
439+
#[inline(always)]
440+
fn log2(&self) -> f32 { log2(*self) }
441+
442+
#[inline(always)]
443+
fn log10(&self) -> f32 { log10(*self) }
444+
445+
#[inline(always)]
446+
fn log_radix(&self) -> f32 { log_radix(*self) as f32 }
447+
448+
#[inline(always)]
449+
fn ilog_radix(&self) -> int { ilog_radix(*self) as int }
450+
451+
#[inline(always)]
452+
fn sqrt(&self) -> f32 { sqrt(*self) }
453+
454+
#[inline(always)]
455+
fn rsqrt(&self) -> f32 { self.sqrt().recip() }
456+
457+
#[inline(always)]
458+
fn cbrt(&self) -> f32 { cbrt(*self) }
459+
460+
/// Converts to degrees, assuming the number is in radians
461+
#[inline(always)]
462+
fn to_degrees(&self) -> f32 { *self * (180.0 / Real::pi::<f32>()) }
463+
464+
/// Converts to radians, assuming the number is in degrees
465+
#[inline(always)]
466+
fn to_radians(&self) -> f32 { *self * (Real::pi::<f32>() / 180.0) }
467+
468+
#[inline(always)]
469+
fn hypot(&self, other: f32) -> f32 { hypot(*self, other) }
470+
471+
#[inline(always)]
472+
fn sin(&self) -> f32 { sin(*self) }
473+
474+
#[inline(always)]
475+
fn cos(&self) -> f32 { cos(*self) }
476+
477+
#[inline(always)]
478+
fn tan(&self) -> f32 { tan(*self) }
479+
480+
#[inline(always)]
481+
fn asin(&self) -> f32 { asin(*self) }
482+
483+
#[inline(always)]
484+
fn acos(&self) -> f32 { acos(*self) }
485+
486+
#[inline(always)]
487+
fn atan(&self) -> f32 { atan(*self) }
488+
489+
#[inline(always)]
490+
fn atan2(&self, other: f32) -> f32 { atan2(*self, other) }
491+
492+
#[inline(always)]
493+
fn sinh(&self) -> f32 { sinh(*self) }
494+
495+
#[inline(always)]
496+
fn cosh(&self) -> f32 { cosh(*self) }
497+
498+
#[inline(always)]
499+
fn tanh(&self) -> f32 { tanh(*self) }
355500
}
356501

357502
/**
@@ -577,11 +722,39 @@ mod tests {
577722
use super::*;
578723
use prelude::*;
579724
725+
macro_rules! assert_fuzzy_eq(
726+
($a:expr, $b:expr) => ({
727+
let a = $a, b = $b;
728+
if !((a - b).abs() < 1.0e-6) {
729+
fail!(fmt!("The values were not approximately equal. Found: %? and %?", a, b));
730+
}
731+
})
732+
)
733+
580734
#[test]
581735
fn test_num() {
582736
num::test_num(10f32, 2f32);
583737
}
584738

739+
#[test]
740+
fn test_real_consts() {
741+
assert_fuzzy_eq!(Real::two_pi::<f32>(), 2f32 * Real::pi::<f32>());
742+
assert_fuzzy_eq!(Real::frac_pi_2::<f32>(), Real::pi::<f32>() / 2f32);
743+
assert_fuzzy_eq!(Real::frac_pi_3::<f32>(), Real::pi::<f32>() / 3f32);
744+
assert_fuzzy_eq!(Real::frac_pi_4::<f32>(), Real::pi::<f32>() / 4f32);
745+
assert_fuzzy_eq!(Real::frac_pi_6::<f32>(), Real::pi::<f32>() / 6f32);
746+
assert_fuzzy_eq!(Real::frac_pi_8::<f32>(), Real::pi::<f32>() / 8f32);
747+
assert_fuzzy_eq!(Real::frac_1_pi::<f32>(), 1f32 / Real::pi::<f32>());
748+
assert_fuzzy_eq!(Real::frac_2_pi::<f32>(), 2f32 / Real::pi::<f32>());
749+
assert_fuzzy_eq!(Real::frac_2_sqrtpi::<f32>(), 2f32 / Real::pi::<f32>().sqrt());
750+
assert_fuzzy_eq!(Real::sqrt2::<f32>(), 2f32.sqrt());
751+
assert_fuzzy_eq!(Real::frac_1_sqrt2::<f32>(), 1f32 / 2f32.sqrt());
752+
assert_fuzzy_eq!(Real::log2_e::<f32>(), Real::e::<f32>().log2());
753+
assert_fuzzy_eq!(Real::log10_e::<f32>(), Real::e::<f32>().log10());
754+
assert_fuzzy_eq!(Real::log_2::<f32>(), 2f32.log());
755+
assert_fuzzy_eq!(Real::log_10::<f32>(), 10f32.log());
756+
}
757+
585758
#[test]
586759
pub fn test_signed() {
587760
assert_eq!(infinity.abs(), infinity);

0 commit comments

Comments
 (0)