about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMarvin Löbel <loebel.marvin@gmail.com>2013-01-21 00:40:02 +0100
committerBrian Anderson <banderson@mozilla.com>2013-02-03 15:37:24 -0800
commitbb9c3ed8764077455b6e726ba49c9845e03f4f0c (patch)
tree49b63de8e1668f3b37719c694971b3879ec82e01
parent05d83017ec249d5a338001acba30f7b717c7507e (diff)
downloadrust-bb9c3ed8764077455b6e726ba49c9845e03f4f0c.tar.gz
rust-bb9c3ed8764077455b6e726ba49c9845e03f4f0c.zip
Added some generic number functions to core::num
Also fixes previous commit not compiling due to not finding Option.
-rw-r--r--src/libcore/num/num.rs89
1 files changed, 89 insertions, 0 deletions
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<self>;
+}
+
+// Generic math functions:
+
+/// Dynamically calculates the value `inf` (`1/0`).
+/// Can fail on integer types.
+#[inline(always)]
+pub pure fn infinity<T: Num One Zero>() -> 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: Num One Zero>() -> 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: Num Zero>() -> 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<T: Num One Zero Eq>(num: &T) -> bool {
+    (*num) == (infinity::<T>())
+}
+
+/// Returns `true` if `num` has the value `-inf` (`-1/0`).
+/// Can fail on integer types.
+#[inline(always)]
+pub pure fn is_neg_infinity<T: Num One Zero Eq>(num: &T) -> bool {
+    (*num) == (neg_infinity::<T>())
+}
+
+/// Returns `true` if `num` has the value `NaN` (is not equal to itself).
+#[inline(always)]
+pub pure fn is_NaN<T: Num Eq>(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<T: Num One Zero Eq>(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<T: Num One Zero>(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