11
11
//! Operations and constants for `f32`
12
12
13
13
use num:: strconv;
14
+ use num:: Signed ;
14
15
use num;
15
16
use option:: Option ;
16
17
use from_str;
@@ -163,38 +164,6 @@ pub fn gt(x: f32, y: f32) -> bool { return x > y; }
163
164
// FIXME (#1999): replace the predicates below with llvm intrinsics or
164
165
// calls to the libmath macros in the rust runtime for performance.
165
166
166
- /// Returns true if `x` is a positive number, including +0.0f320 and +Infinity
167
- #[ inline( always) ]
168
- pub fn is_positive ( x : f32 ) -> bool {
169
- x > 0.0f32 || ( 1.0f32 /x) == infinity
170
- }
171
-
172
- /// Returns true if `x` is a negative number, including -0.0f320 and -Infinity
173
- #[ inline( always) ]
174
- pub fn is_negative ( x : f32 ) -> bool {
175
- x < 0.0f32 || ( 1.0f32 /x) == neg_infinity
176
- }
177
-
178
- /**
179
- * Returns true if `x` is a negative number, including -0.0f320 and -Infinity
180
- *
181
- * This is the same as `f32::is_negative`.
182
- */
183
- #[ inline( always) ]
184
- pub fn is_nonpositive ( x : f32 ) -> bool {
185
- return x < 0.0f32 || ( 1.0f32 /x) == neg_infinity;
186
- }
187
-
188
- /**
189
- * Returns true if `x` is a positive number, including +0.0f320 and +Infinity
190
- *
191
- * This is the same as `f32::is_positive`.)
192
- */
193
- #[ inline( always) ]
194
- pub fn is_nonnegative ( x : f32 ) -> bool {
195
- return x > 0.0f32 || ( 1.0f32 /x) == infinity;
196
- }
197
-
198
167
/// Returns true if `x` is a zero number (positive or negative zero)
199
168
#[ inline( always) ]
200
169
pub fn is_zero ( x : f32 ) -> bool {
@@ -259,11 +228,6 @@ pub mod consts {
259
228
pub static ln_10: f32 = 2.30258509299404568401799145468436421_f32 ;
260
229
}
261
230
262
- #[ inline( always) ]
263
- pub fn signbit ( x : f32 ) -> int {
264
- if is_negative ( x) { return 1 ; } else { return 0 ; }
265
- }
266
-
267
231
#[ inline( always) ]
268
232
pub fn logarithm ( n : f32 , b : f32 ) -> f32 {
269
233
return log2 ( n) / log2 ( b) ;
@@ -351,15 +315,41 @@ impl Neg<f32> for f32 {
351
315
fn neg ( & self ) -> f32 { -* self }
352
316
}
353
317
318
+ impl Signed for f32 {
319
+ /// Computes the absolute value. Returns `NaN` if the number is `NaN`.
320
+ #[ inline( always) ]
321
+ fn abs ( & self ) -> f32 { abs ( * self ) }
322
+
323
+ /**
324
+ * # Returns
325
+ *
326
+ * - `1.0` if the number is positive, `+0.0` or `infinity`
327
+ * - `-1.0` if the number is negative, `-0.0` or `neg_infinity`
328
+ * - `NaN` if the number is `NaN`
329
+ */
330
+ #[ inline( always) ]
331
+ fn signum ( & self ) -> f32 {
332
+ if is_NaN ( * self ) { NaN } else { copysign ( 1.0 , * self ) }
333
+ }
334
+
335
+ /// Returns `true` if the number is positive, including `+0.0` and `infinity`
336
+ #[ inline( always) ]
337
+ fn is_positive ( & self ) -> bool { * self > 0.0 || ( 1.0 / * self ) == infinity }
338
+
339
+ /// Returns `true` if the number is negative, including `-0.0` and `neg_infinity`
340
+ #[ inline( always) ]
341
+ fn is_negative ( & self ) -> bool { * self < 0.0 || ( 1.0 / * self ) == neg_infinity }
342
+ }
343
+
354
344
impl num:: Round for f32 {
355
345
#[ inline( always) ]
356
346
fn round ( & self , mode : num:: RoundMode ) -> f32 {
357
347
match mode {
358
348
num:: RoundDown => floor ( * self ) ,
359
349
num:: RoundUp => ceil ( * self ) ,
360
- num:: RoundToZero if is_negative ( * self ) => ceil ( * self ) ,
350
+ num:: RoundToZero if self . is_negative ( ) => ceil ( * self ) ,
361
351
num:: RoundToZero => floor ( * self ) ,
362
- num:: RoundFromZero if is_negative ( * self ) => floor ( * self ) ,
352
+ num:: RoundFromZero if self . is_negative ( ) => floor ( * self ) ,
363
353
num:: RoundFromZero => ceil ( * self )
364
354
}
365
355
}
@@ -370,7 +360,7 @@ impl num::Round for f32 {
370
360
fn ceil ( & self ) -> f32 { ceil ( * self ) }
371
361
#[ inline( always) ]
372
362
fn fract ( & self ) -> f32 {
373
- if is_negative ( * self ) {
363
+ if self . is_negative ( ) {
374
364
( * self ) - ceil ( * self )
375
365
} else {
376
366
( * self ) - floor ( * self )
@@ -595,6 +585,50 @@ impl num::FromStrRadix for f32 {
595
585
}
596
586
}
597
587
588
+ #[ cfg( test) ]
589
+ mod tests {
590
+ use f32:: * ;
591
+
592
+ #[ test]
593
+ pub fn test_signed ( ) {
594
+ assert_eq ! ( infinity. abs( ) , infinity) ;
595
+ assert_eq ! ( 1f32 . abs( ) , 1f32 ) ;
596
+ assert_eq ! ( 0f32 . abs( ) , 0f32 ) ;
597
+ assert_eq ! ( ( -0f32 ) . abs( ) , 0f32 ) ;
598
+ assert_eq ! ( ( -1f32 ) . abs( ) , 1f32 ) ;
599
+ assert_eq ! ( neg_infinity. abs( ) , infinity) ;
600
+ assert_eq ! ( ( 1f32 /neg_infinity) . abs( ) , 0f32 ) ;
601
+ assert ! ( is_NaN( NaN . abs( ) ) ) ;
602
+
603
+ assert_eq ! ( infinity. signum( ) , 1f32 ) ;
604
+ assert_eq ! ( 1f32 . signum( ) , 1f32 ) ;
605
+ assert_eq ! ( 0f32 . signum( ) , 1f32 ) ;
606
+ assert_eq ! ( ( -0f32 ) . signum( ) , -1f32 ) ;
607
+ assert_eq ! ( ( -1f32 ) . signum( ) , -1f32 ) ;
608
+ assert_eq ! ( neg_infinity. signum( ) , -1f32 ) ;
609
+ assert_eq ! ( ( 1f32 /neg_infinity) . signum( ) , -1f32 ) ;
610
+ assert ! ( is_NaN( NaN . signum( ) ) ) ;
611
+
612
+ assert ! ( infinity. is_positive( ) ) ;
613
+ assert ! ( 1f32 . is_positive( ) ) ;
614
+ assert ! ( 0f32 . is_positive( ) ) ;
615
+ assert ! ( !( -0f32 ) . is_positive( ) ) ;
616
+ assert ! ( !( -1f32 ) . is_positive( ) ) ;
617
+ assert ! ( !neg_infinity. is_positive( ) ) ;
618
+ assert ! ( !( 1f32 /neg_infinity) . is_positive( ) ) ;
619
+ assert ! ( !NaN . is_positive( ) ) ;
620
+
621
+ assert ! ( !infinity. is_negative( ) ) ;
622
+ assert ! ( !1f32 . is_negative( ) ) ;
623
+ assert ! ( !0f32 . is_negative( ) ) ;
624
+ assert ! ( ( -0f32 ) . is_negative( ) ) ;
625
+ assert ! ( ( -1f32 ) . is_negative( ) ) ;
626
+ assert ! ( neg_infinity. is_negative( ) ) ;
627
+ assert ! ( ( 1f32 /neg_infinity) . is_negative( ) ) ;
628
+ assert ! ( !NaN . is_negative( ) ) ;
629
+ }
630
+ }
631
+
598
632
//
599
633
// Local Variables:
600
634
// mode: rust
0 commit comments