Skip to content

Commit 4c07f5e

Browse files
committed
Add Int, Uint and Float traits for primitive numbers
1 parent b624210 commit 4c07f5e

File tree

8 files changed

+122
-48
lines changed

8 files changed

+122
-48
lines changed

src/libcore/core.rc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ pub use num::{Signed, Unsigned, Integer};
108108
pub use num::{Round, Fractional, Real, RealExt};
109109
pub use num::{Bitwise, Bounded};
110110
pub use num::{Primitive, PrimitiveInt};
111+
pub use num::{Int, Uint, Float};
111112
pub use ptr::Ptr;
112113
pub use to_str::ToStr;
113114
pub use clone::Clone;

src/libcore/num/f32.rs

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,6 @@ pub static infinity: f32 = 1.0_f32/0.0_f32;
114114

115115
pub static neg_infinity: f32 = -1.0_f32/0.0_f32;
116116

117-
#[inline(always)]
118-
pub fn is_NaN(f: f32) -> bool { f != f }
119-
120117
#[inline(always)]
121118
pub fn add(x: f32, y: f32) -> f32 { return x + y; }
122119

@@ -154,18 +151,6 @@ pub fn gt(x: f32, y: f32) -> bool { return x > y; }
154151
// FIXME (#1999): replace the predicates below with llvm intrinsics or
155152
// calls to the libmath macros in the rust runtime for performance.
156153

157-
/// Returns true if `x`is an infinite number
158-
#[inline(always)]
159-
pub fn is_infinite(x: f32) -> bool {
160-
return x == infinity || x == neg_infinity;
161-
}
162-
163-
/// Returns true if `x`is a finite number
164-
#[inline(always)]
165-
pub fn is_finite(x: f32) -> bool {
166-
return !(is_NaN(x) || is_infinite(x));
167-
}
168-
169154
// FIXME (#1999): add is_normal, is_subnormal, and fpclassify.
170155

171156
/* Module: consts */
@@ -313,7 +298,7 @@ impl Signed for f32 {
313298
///
314299
#[inline(always)]
315300
fn signum(&self) -> f32 {
316-
if is_NaN(*self) { NaN } else { copysign(1.0, *self) }
301+
if self.is_NaN() { NaN } else { copysign(1.0, *self) }
317302
}
318303

319304
/// Returns `true` if the number is positive, including `+0.0` and `infinity`
@@ -517,6 +502,35 @@ impl Primitive for f32 {
517502
fn bytes() -> uint { Primitive::bits::<f32>() / 8 }
518503
}
519504

505+
impl Float for f32 {
506+
#[inline(always)]
507+
fn NaN() -> f32 { 0.0 / 0.0 }
508+
509+
#[inline(always)]
510+
fn infinity() -> f32 { 1.0 / 0.0 }
511+
512+
#[inline(always)]
513+
fn neg_infinity() -> f32 { -1.0 / 0.0 }
514+
515+
#[inline(always)]
516+
fn neg_zero() -> f32 { -0.0 }
517+
518+
#[inline(always)]
519+
fn is_NaN(&self) -> bool { *self != *self }
520+
521+
/// Returns `true` if the number is infinite
522+
#[inline(always)]
523+
fn is_infinite(&self) -> bool {
524+
*self == Float::infinity() || *self == Float::neg_infinity()
525+
}
526+
527+
/// Returns `true` if the number is finite
528+
#[inline(always)]
529+
fn is_finite(&self) -> bool {
530+
!(self.is_NaN() || self.is_infinite())
531+
}
532+
}
533+
520534
//
521535
// Section: String Conversions
522536
//
@@ -852,7 +866,7 @@ mod tests {
852866
assert_eq!((-1f32).abs(), 1f32);
853867
assert_eq!(neg_infinity.abs(), infinity);
854868
assert_eq!((1f32/neg_infinity).abs(), 0f32);
855-
assert!(is_NaN(NaN.abs()));
869+
assert!(NaN.abs().is_NaN());
856870

857871
assert_eq!(infinity.signum(), 1f32);
858872
assert_eq!(1f32.signum(), 1f32);
@@ -861,7 +875,7 @@ mod tests {
861875
assert_eq!((-1f32).signum(), -1f32);
862876
assert_eq!(neg_infinity.signum(), -1f32);
863877
assert_eq!((1f32/neg_infinity).signum(), -1f32);
864-
assert!(is_NaN(NaN.signum()));
878+
assert!(NaN.signum().is_NaN());
865879

866880
assert!(infinity.is_positive());
867881
assert!(1f32.is_positive());

src/libcore/num/f64.rs

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,6 @@ pub static infinity: f64 = 1.0_f64/0.0_f64;
138138

139139
pub static neg_infinity: f64 = -1.0_f64/0.0_f64;
140140

141-
#[inline(always)]
142-
pub fn is_NaN(f: f64) -> bool { f != f }
143-
144141
#[inline(always)]
145142
pub fn add(x: f64, y: f64) -> f64 { return x + y; }
146143

@@ -174,18 +171,6 @@ pub fn ge(x: f64, y: f64) -> bool { return x >= y; }
174171
#[inline(always)]
175172
pub fn gt(x: f64, y: f64) -> bool { return x > y; }
176173

177-
/// Returns true if `x`is an infinite number
178-
#[inline(always)]
179-
pub fn is_infinite(x: f64) -> bool {
180-
return x == infinity || x == neg_infinity;
181-
}
182-
183-
/// Returns true if `x` is a finite number
184-
#[inline(always)]
185-
pub fn is_finite(x: f64) -> bool {
186-
return !(is_NaN(x) || is_infinite(x));
187-
}
188-
189174

190175
// FIXME (#1999): add is_normal, is_subnormal, and fpclassify
191176

@@ -323,7 +308,7 @@ impl Signed for f64 {
323308
///
324309
#[inline(always)]
325310
fn signum(&self) -> f64 {
326-
if is_NaN(*self) { NaN } else { copysign(1.0, *self) }
311+
if self.is_NaN() { NaN } else { copysign(1.0, *self) }
327312
}
328313

329314
/// Returns `true` if the number is positive, including `+0.0` and `infinity`
@@ -557,6 +542,35 @@ impl Primitive for f64 {
557542
fn bytes() -> uint { Primitive::bits::<f64>() / 8 }
558543
}
559544

545+
impl Float for f64 {
546+
#[inline(always)]
547+
fn NaN() -> f64 { 0.0 / 0.0 }
548+
549+
#[inline(always)]
550+
fn infinity() -> f64 { 1.0 / 0.0 }
551+
552+
#[inline(always)]
553+
fn neg_infinity() -> f64 { -1.0 / 0.0 }
554+
555+
#[inline(always)]
556+
fn neg_zero() -> f64 { -0.0 }
557+
558+
#[inline(always)]
559+
fn is_NaN(&self) -> bool { *self != *self }
560+
561+
/// Returns `true` if the number is infinite
562+
#[inline(always)]
563+
fn is_infinite(&self) -> bool {
564+
*self == Float::infinity() || *self == Float::neg_infinity()
565+
}
566+
567+
/// Returns `true` if the number is finite
568+
#[inline(always)]
569+
fn is_finite(&self) -> bool {
570+
!(self.is_NaN() || self.is_infinite())
571+
}
572+
}
573+
560574
//
561575
// Section: String Conversions
562576
//
@@ -893,7 +907,7 @@ mod tests {
893907
assert_eq!((-1f64).abs(), 1f64);
894908
assert_eq!(neg_infinity.abs(), infinity);
895909
assert_eq!((1f64/neg_infinity).abs(), 0f64);
896-
assert!(is_NaN(NaN.abs()));
910+
assert!(NaN.abs().is_NaN());
897911

898912
assert_eq!(infinity.signum(), 1f64);
899913
assert_eq!(1f64.signum(), 1f64);
@@ -902,7 +916,7 @@ mod tests {
902916
assert_eq!((-1f64).signum(), -1f64);
903917
assert_eq!(neg_infinity.signum(), -1f64);
904918
assert_eq!((1f64/neg_infinity).signum(), -1f64);
905-
assert!(is_NaN(NaN.signum()));
919+
assert!(NaN.signum().is_NaN());
906920

907921
assert!(infinity.is_positive());
908922
assert!(1f64.is_positive());

src/libcore/num/float.rs

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -337,13 +337,6 @@ pub fn pow_with_uint(base: uint, pow: uint) -> float {
337337
return total;
338338
}
339339
340-
#[inline(always)]
341-
pub fn is_infinite(x: float) -> bool { f64::is_infinite(x as f64) }
342-
#[inline(always)]
343-
pub fn is_finite(x: float) -> bool { f64::is_finite(x as f64) }
344-
#[inline(always)]
345-
pub fn is_NaN(x: float) -> bool { f64::is_NaN(x as f64) }
346-
347340
#[inline(always)]
348341
pub fn abs(x: float) -> float {
349342
f64::abs(x as f64) as float
@@ -677,7 +670,7 @@ impl Signed for float {
677670
///
678671
#[inline(always)]
679672
fn signum(&self) -> float {
680-
if is_NaN(*self) { NaN } else { f64::copysign(1.0, *self as f64) as float }
673+
if self.is_NaN() { NaN } else { f64::copysign(1.0, *self as f64) as float }
681674
}
682675
683676
/// Returns `true` if the number is positive, including `+0.0` and `infinity`
@@ -697,6 +690,35 @@ impl Primitive for float {
697690
fn bytes() -> uint { Primitive::bytes::<f64>() }
698691
}
699692
693+
impl Float for float {
694+
#[inline(always)]
695+
fn NaN() -> float { 0.0 / 0.0 }
696+
697+
#[inline(always)]
698+
fn infinity() -> float { 1.0 / 0.0 }
699+
700+
#[inline(always)]
701+
fn neg_infinity() -> float { -1.0 / 0.0 }
702+
703+
#[inline(always)]
704+
fn neg_zero() -> float { -0.0 }
705+
706+
#[inline(always)]
707+
fn is_NaN(&self) -> bool { *self != *self }
708+
709+
/// Returns `true` if the number is infinite
710+
#[inline(always)]
711+
fn is_infinite(&self) -> bool {
712+
*self == Float::infinity() || *self == Float::neg_infinity()
713+
}
714+
715+
/// Returns `true` if the number is finite
716+
#[inline(always)]
717+
fn is_finite(&self) -> bool {
718+
!(self.is_NaN() || self.is_infinite())
719+
}
720+
}
721+
700722
#[cfg(test)]
701723
mod tests {
702724
use super::*;
@@ -814,7 +836,7 @@ mod tests {
814836
assert_eq!((-1f).abs(), 1f);
815837
assert_eq!(neg_infinity.abs(), infinity);
816838
assert_eq!((1f/neg_infinity).abs(), 0f);
817-
assert!(is_NaN(NaN.abs()));
839+
assert!(NaN.abs().is_NaN());
818840
819841
assert_eq!(infinity.signum(), 1f);
820842
assert_eq!(1f.signum(), 1f);
@@ -823,7 +845,7 @@ mod tests {
823845
assert_eq!((-1f).signum(), -1f);
824846
assert_eq!(neg_infinity.signum(), -1f);
825847
assert_eq!((1f/neg_infinity).signum(), -1f);
826-
assert!(is_NaN(NaN.signum()));
848+
assert!(NaN.signum().is_NaN());
827849
828850
assert!(infinity.is_positive());
829851
assert!(1f.is_positive());
@@ -878,7 +900,7 @@ mod tests {
878900
assert_eq!(from_str(~"-inf"), Some(neg_infinity));
879901
// note: NaN != NaN, hence this slightly complex test
880902
match from_str(~"NaN") {
881-
Some(f) => assert!(is_NaN(f)),
903+
Some(f) => assert!(f.is_NaN()),
882904
None => fail!()
883905
}
884906
// note: -0 == 0, hence these slightly more complex tests
@@ -925,7 +947,7 @@ mod tests {
925947
assert_eq!(from_str_hex(~"-inf"), Some(neg_infinity));
926948
// note: NaN != NaN, hence this slightly complex test
927949
match from_str_hex(~"NaN") {
928-
Some(f) => assert!(is_NaN(f)),
950+
Some(f) => assert!(f.is_NaN()),
929951
None => fail!()
930952
}
931953
// note: -0 == 0, hence these slightly more complex tests

src/libcore/num/int-template.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,8 @@ impl Bounded for T {
447447
448448
impl PrimitiveInt for T {}
449449
450+
impl Int for T {}
451+
450452
// String conversion functions and impl str -> num
451453
452454
/// Parse a string as a number in base 10.

src/libcore/num/num.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,24 @@ pub trait Uint: PrimitiveInt
228228
pub trait Int: PrimitiveInt
229229
+ Signed {}
230230

231+
///
232+
/// Primitive floating point numbers. This trait should only be implemented
233+
/// for the `f32`, `f64`, and `float` types.
234+
///
235+
pub trait Float: Real
236+
+ Signed
237+
+ Primitive {
238+
// FIXME (#5527): These should be associated constants
239+
fn NaN() -> Self;
240+
fn infinity() -> Self;
241+
fn neg_infinity() -> Self;
242+
fn neg_zero() -> Self;
243+
244+
fn is_NaN(&self) -> bool;
245+
fn is_infinite(&self) -> bool;
246+
fn is_finite(&self) -> bool;
247+
}
248+
231249
///
232250
/// Cast from one machine scalar to another
233251
///

src/libcore/num/uint-template.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,8 @@ impl Bounded for T {
279279
280280
impl PrimitiveInt for T {}
281281
282+
impl Uint for T {}
283+
282284
// String conversion functions and impl str -> num
283285
284286
/// Parse a string as a number in base 10.

src/libcore/prelude.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ pub use num::{Signed, Unsigned, Integer};
4242
pub use num::{Round, Fractional, Real, RealExt};
4343
pub use num::{Bitwise, Bounded};
4444
pub use num::{Primitive, PrimitiveInt};
45+
pub use num::{Int, Uint, Float};
4546
pub use path::GenericPath;
4647
pub use path::Path;
4748
pub use path::PosixPath;

0 commit comments

Comments
 (0)