From bb9c3ed8764077455b6e726ba49c9845e03f4f0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20L=C3=B6bel?= Date: Mon, 21 Jan 2013 00:40:02 +0100 Subject: [PATCH] Added some generic number functions to core::num Also fixes previous commit not compiling due to not finding Option. --- src/libcore/num/num.rs | 89 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/src/libcore/num/num.rs b/src/libcore/num/num.rs index 5d26696f018..15f9754873f 100644 --- a/src/libcore/num/num.rs +++ b/src/libcore/num/num.rs @@ -59,4 +59,93 @@ pub trait ToStrRadix { pub trait FromStrRadix { static pub pure fn from_str_radix(str: &str, radix: uint) -> Option; +} + +// Generic math functions: + +/// Dynamically calculates the value `inf` (`1/0`). +/// Can fail on integer types. +#[inline(always)] +pub pure fn infinity() -> T { + let _0: T = Zero::zero(); + let _1: T = One::one(); + _1 / _0 +} + +/// Dynamically calculates the value `-inf` (`-1/0`). +/// Can fail on integer types. +#[inline(always)] +pub pure fn neg_infinity() -> T { + let _0: T = Zero::zero(); + let _1: T = One::one(); + - _1 / _0 +} + +/// Dynamically calculates the value `NaN` (`0/0`). +/// Can fail on integer types. +#[inline(always)] +pub pure fn NaN() -> T { + let _0: T = Zero::zero(); + _0 / _0 +} + +/// Returns `true` if `num` has the value `inf` (`1/0`). +/// Can fail on integer types. +#[inline(always)] +pub pure fn is_infinity(num: &T) -> bool { + (*num) == (infinity::()) +} + +/// Returns `true` if `num` has the value `-inf` (`-1/0`). +/// Can fail on integer types. +#[inline(always)] +pub pure fn is_neg_infinity(num: &T) -> bool { + (*num) == (neg_infinity::()) +} + +/// Returns `true` if `num` has the value `NaN` (is not equal to itself). +#[inline(always)] +pub pure fn is_NaN(num: &T) -> bool { + (*num) != (*num) +} + +/// Returns `true` if `num` has the value `-0` (`1/num == -1/0`). +/// Can fail on integer types. +#[inline(always)] +pub pure fn is_neg_zero(num: &T) -> bool { + let _1: T = One::one(); + let _0: T = Zero::zero(); + *num == _0 && is_neg_infinity(&(_1 / *num)) +} + +/** + * Calculates a power to a given radix, optimized for uint `pow` and `radix`. + * + * Returns `radix^pow` as `T`. + * + * Note: + * Also returns `1` for `0^0`, despite that technically being an + * undefined number. The Reason for this is twofold: + * - If code written to use this function cares about that special case, it's + * probably going to catch it before making the call. + * - If code written to use this function doesn't care about it, it's + * probably assuming that `x^0` always equals `1`. + */ +pub pure fn pow_with_uint(radix: uint, pow: uint) -> T { + let _0: T = Zero::zero(); + let _1: T = One::one(); + + if pow == 0u { return _1; } + if radix == 0u { return _0; } + let mut my_pow = pow; + let mut total = _1; + let mut multiplier = Num::from_int(radix as int); + while (my_pow > 0u) { + if my_pow % 2u == 1u { + total *= multiplier; + } + my_pow /= 2u; + multiplier *= multiplier; + } + total } \ No newline at end of file