]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
11 | //! Operations and constants for 32-bits floats (`f32` type) | |
12 | ||
13 | #![doc(primitive = "f32")] | |
14 | // FIXME: MIN_VALUE and MAX_VALUE literals are parsed as -inf and inf #14353 | |
15 | #![allow(overflowing_literals)] | |
16 | ||
17 | #![stable] | |
18 | ||
19 | use intrinsics; | |
20 | use mem; | |
21 | use num::Float; | |
22 | use num::FpCategory as Fp; | |
23 | use option::Option; | |
24 | ||
25 | #[unstable = "pending integer conventions"] | |
26 | pub const RADIX: uint = 2u; | |
27 | ||
28 | #[unstable = "pending integer conventions"] | |
29 | pub const MANTISSA_DIGITS: uint = 24u; | |
30 | #[unstable = "pending integer conventions"] | |
31 | pub const DIGITS: uint = 6u; | |
32 | ||
33 | #[stable] | |
34 | pub const EPSILON: f32 = 1.19209290e-07_f32; | |
35 | ||
36 | /// Smallest finite f32 value | |
37 | #[stable] | |
38 | pub const MIN_VALUE: f32 = -3.40282347e+38_f32; | |
39 | /// Smallest positive, normalized f32 value | |
40 | #[stable] | |
41 | pub const MIN_POS_VALUE: f32 = 1.17549435e-38_f32; | |
42 | /// Largest finite f32 value | |
43 | #[stable] | |
44 | pub const MAX_VALUE: f32 = 3.40282347e+38_f32; | |
45 | ||
46 | #[unstable = "pending integer conventions"] | |
47 | pub const MIN_EXP: int = -125; | |
48 | #[unstable = "pending integer conventions"] | |
49 | pub const MAX_EXP: int = 128; | |
50 | ||
51 | #[unstable = "pending integer conventions"] | |
52 | pub const MIN_10_EXP: int = -37; | |
53 | #[unstable = "pending integer conventions"] | |
54 | pub const MAX_10_EXP: int = 38; | |
55 | ||
56 | #[stable] | |
57 | pub const NAN: f32 = 0.0_f32/0.0_f32; | |
58 | #[stable] | |
59 | pub const INFINITY: f32 = 1.0_f32/0.0_f32; | |
60 | #[stable] | |
61 | pub const NEG_INFINITY: f32 = -1.0_f32/0.0_f32; | |
62 | ||
63 | /// Various useful constants. | |
64 | #[unstable = "naming scheme needs to be revisited"] | |
65 | pub mod consts { | |
66 | // FIXME: replace with mathematical constants from cmath. | |
67 | ||
68 | /// Archimedes' constant | |
69 | pub const PI: f32 = 3.14159265358979323846264338327950288_f32; | |
70 | ||
71 | /// pi * 2.0 | |
72 | pub const PI_2: f32 = 6.28318530717958647692528676655900576_f32; | |
73 | ||
74 | /// pi/2.0 | |
75 | pub const FRAC_PI_2: f32 = 1.57079632679489661923132169163975144_f32; | |
76 | ||
77 | /// pi/3.0 | |
78 | pub const FRAC_PI_3: f32 = 1.04719755119659774615421446109316763_f32; | |
79 | ||
80 | /// pi/4.0 | |
81 | pub const FRAC_PI_4: f32 = 0.785398163397448309615660845819875721_f32; | |
82 | ||
83 | /// pi/6.0 | |
84 | pub const FRAC_PI_6: f32 = 0.52359877559829887307710723054658381_f32; | |
85 | ||
86 | /// pi/8.0 | |
87 | pub const FRAC_PI_8: f32 = 0.39269908169872415480783042290993786_f32; | |
88 | ||
89 | /// 1.0/pi | |
90 | pub const FRAC_1_PI: f32 = 0.318309886183790671537767526745028724_f32; | |
91 | ||
92 | /// 2.0/pi | |
93 | pub const FRAC_2_PI: f32 = 0.636619772367581343075535053490057448_f32; | |
94 | ||
95 | /// 2.0/sqrt(pi) | |
96 | pub const FRAC_2_SQRTPI: f32 = 1.12837916709551257389615890312154517_f32; | |
97 | ||
98 | /// sqrt(2.0) | |
99 | pub const SQRT2: f32 = 1.41421356237309504880168872420969808_f32; | |
100 | ||
101 | /// 1.0/sqrt(2.0) | |
102 | pub const FRAC_1_SQRT2: f32 = 0.707106781186547524400844362104849039_f32; | |
103 | ||
104 | /// Euler's number | |
105 | pub const E: f32 = 2.71828182845904523536028747135266250_f32; | |
106 | ||
107 | /// log2(e) | |
108 | pub const LOG2_E: f32 = 1.44269504088896340735992468100189214_f32; | |
109 | ||
110 | /// log10(e) | |
111 | pub const LOG10_E: f32 = 0.434294481903251827651128918916605082_f32; | |
112 | ||
113 | /// ln(2.0) | |
114 | pub const LN_2: f32 = 0.693147180559945309417232121458176568_f32; | |
115 | ||
116 | /// ln(10.0) | |
117 | pub const LN_10: f32 = 2.30258509299404568401799145468436421_f32; | |
118 | } | |
119 | ||
120 | #[unstable = "trait is unstable"] | |
121 | impl Float for f32 { | |
122 | #[inline] | |
123 | fn nan() -> f32 { NAN } | |
124 | ||
125 | #[inline] | |
126 | fn infinity() -> f32 { INFINITY } | |
127 | ||
128 | #[inline] | |
129 | fn neg_infinity() -> f32 { NEG_INFINITY } | |
130 | ||
131 | #[inline] | |
132 | fn zero() -> f32 { 0.0 } | |
133 | ||
134 | #[inline] | |
135 | fn neg_zero() -> f32 { -0.0 } | |
136 | ||
137 | #[inline] | |
138 | fn one() -> f32 { 1.0 } | |
139 | ||
140 | /// Returns `true` if the number is NaN. | |
141 | #[inline] | |
142 | fn is_nan(self) -> bool { self != self } | |
143 | ||
144 | /// Returns `true` if the number is infinite. | |
145 | #[inline] | |
146 | fn is_infinite(self) -> bool { | |
147 | self == Float::infinity() || self == Float::neg_infinity() | |
148 | } | |
149 | ||
150 | /// Returns `true` if the number is neither infinite or NaN. | |
151 | #[inline] | |
152 | fn is_finite(self) -> bool { | |
153 | !(self.is_nan() || self.is_infinite()) | |
154 | } | |
155 | ||
156 | /// Returns `true` if the number is neither zero, infinite, subnormal or NaN. | |
157 | #[inline] | |
158 | fn is_normal(self) -> bool { | |
159 | self.classify() == Fp::Normal | |
160 | } | |
161 | ||
162 | /// Returns the floating point category of the number. If only one property | |
163 | /// is going to be tested, it is generally faster to use the specific | |
164 | /// predicate instead. | |
165 | fn classify(self) -> Fp { | |
166 | const EXP_MASK: u32 = 0x7f800000; | |
167 | const MAN_MASK: u32 = 0x007fffff; | |
168 | ||
169 | let bits: u32 = unsafe { mem::transmute(self) }; | |
170 | match (bits & MAN_MASK, bits & EXP_MASK) { | |
171 | (0, 0) => Fp::Zero, | |
172 | (_, 0) => Fp::Subnormal, | |
173 | (0, EXP_MASK) => Fp::Infinite, | |
174 | (_, EXP_MASK) => Fp::Nan, | |
175 | _ => Fp::Normal, | |
176 | } | |
177 | } | |
178 | ||
179 | #[inline] | |
180 | #[deprecated] | |
181 | fn mantissa_digits(_: Option<f32>) -> uint { MANTISSA_DIGITS } | |
182 | ||
183 | #[inline] | |
184 | #[deprecated] | |
185 | fn digits(_: Option<f32>) -> uint { DIGITS } | |
186 | ||
187 | #[inline] | |
188 | #[deprecated] | |
189 | fn epsilon() -> f32 { EPSILON } | |
190 | ||
191 | #[inline] | |
192 | #[deprecated] | |
193 | fn min_exp(_: Option<f32>) -> int { MIN_EXP } | |
194 | ||
195 | #[inline] | |
196 | #[deprecated] | |
197 | fn max_exp(_: Option<f32>) -> int { MAX_EXP } | |
198 | ||
199 | #[inline] | |
200 | #[deprecated] | |
201 | fn min_10_exp(_: Option<f32>) -> int { MIN_10_EXP } | |
202 | ||
203 | #[inline] | |
204 | #[deprecated] | |
205 | fn max_10_exp(_: Option<f32>) -> int { MAX_10_EXP } | |
206 | ||
207 | #[inline] | |
208 | #[deprecated] | |
209 | fn min_value() -> f32 { MIN_VALUE } | |
210 | ||
211 | #[inline] | |
212 | #[deprecated] | |
213 | fn min_pos_value(_: Option<f32>) -> f32 { MIN_POS_VALUE } | |
214 | ||
215 | #[inline] | |
216 | #[deprecated] | |
217 | fn max_value() -> f32 { MAX_VALUE } | |
218 | ||
219 | /// Returns the mantissa, exponent and sign as integers. | |
220 | fn integer_decode(self) -> (u64, i16, i8) { | |
221 | let bits: u32 = unsafe { mem::transmute(self) }; | |
222 | let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 }; | |
223 | let mut exponent: i16 = ((bits >> 23) & 0xff) as i16; | |
224 | let mantissa = if exponent == 0 { | |
225 | (bits & 0x7fffff) << 1 | |
226 | } else { | |
227 | (bits & 0x7fffff) | 0x800000 | |
228 | }; | |
229 | // Exponent bias + mantissa shift | |
230 | exponent -= 127 + 23; | |
231 | (mantissa as u64, exponent, sign) | |
232 | } | |
233 | ||
234 | /// Rounds towards minus infinity. | |
235 | #[inline] | |
236 | fn floor(self) -> f32 { | |
237 | unsafe { intrinsics::floorf32(self) } | |
238 | } | |
239 | ||
240 | /// Rounds towards plus infinity. | |
241 | #[inline] | |
242 | fn ceil(self) -> f32 { | |
243 | unsafe { intrinsics::ceilf32(self) } | |
244 | } | |
245 | ||
246 | /// Rounds to nearest integer. Rounds half-way cases away from zero. | |
247 | #[inline] | |
248 | fn round(self) -> f32 { | |
249 | unsafe { intrinsics::roundf32(self) } | |
250 | } | |
251 | ||
252 | /// Returns the integer part of the number (rounds towards zero). | |
253 | #[inline] | |
254 | fn trunc(self) -> f32 { | |
255 | unsafe { intrinsics::truncf32(self) } | |
256 | } | |
257 | ||
258 | /// The fractional part of the number, satisfying: | |
259 | /// | |
260 | /// ```rust | |
261 | /// use core::num::Float; | |
262 | /// | |
263 | /// let x = 1.65f32; | |
264 | /// assert!(x == x.trunc() + x.fract()) | |
265 | /// ``` | |
266 | #[inline] | |
267 | fn fract(self) -> f32 { self - self.trunc() } | |
268 | ||
269 | /// Computes the absolute value of `self`. Returns `Float::nan()` if the | |
270 | /// number is `Float::nan()`. | |
271 | #[inline] | |
272 | fn abs(self) -> f32 { | |
273 | unsafe { intrinsics::fabsf32(self) } | |
274 | } | |
275 | ||
276 | /// Returns a number that represents the sign of `self`. | |
277 | /// | |
278 | /// - `1.0` if the number is positive, `+0.0` or `Float::infinity()` | |
279 | /// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()` | |
280 | /// - `Float::nan()` if the number is `Float::nan()` | |
281 | #[inline] | |
282 | fn signum(self) -> f32 { | |
283 | if self.is_nan() { | |
284 | Float::nan() | |
285 | } else { | |
286 | unsafe { intrinsics::copysignf32(1.0, self) } | |
287 | } | |
288 | } | |
289 | ||
290 | /// Returns `true` if `self` is positive, including `+0.0` and | |
291 | /// `Float::infinity()`. | |
292 | #[inline] | |
293 | fn is_positive(self) -> bool { | |
294 | self > 0.0 || (1.0 / self) == Float::infinity() | |
295 | } | |
296 | ||
297 | /// Returns `true` if `self` is negative, including `-0.0` and | |
298 | /// `Float::neg_infinity()`. | |
299 | #[inline] | |
300 | fn is_negative(self) -> bool { | |
301 | self < 0.0 || (1.0 / self) == Float::neg_infinity() | |
302 | } | |
303 | ||
304 | /// Fused multiply-add. Computes `(self * a) + b` with only one rounding | |
305 | /// error. This produces a more accurate result with better performance than | |
306 | /// a separate multiplication operation followed by an add. | |
307 | #[inline] | |
308 | fn mul_add(self, a: f32, b: f32) -> f32 { | |
309 | unsafe { intrinsics::fmaf32(self, a, b) } | |
310 | } | |
311 | ||
312 | /// Returns the reciprocal (multiplicative inverse) of the number. | |
313 | #[inline] | |
314 | fn recip(self) -> f32 { 1.0 / self } | |
315 | ||
316 | #[inline] | |
317 | fn powi(self, n: i32) -> f32 { | |
318 | unsafe { intrinsics::powif32(self, n) } | |
319 | } | |
320 | ||
321 | #[inline] | |
322 | fn powf(self, n: f32) -> f32 { | |
323 | unsafe { intrinsics::powf32(self, n) } | |
324 | } | |
325 | ||
326 | #[inline] | |
327 | fn sqrt(self) -> f32 { | |
328 | if self < 0.0 { | |
329 | NAN | |
330 | } else { | |
331 | unsafe { intrinsics::sqrtf32(self) } | |
332 | } | |
333 | } | |
334 | ||
335 | #[inline] | |
336 | fn rsqrt(self) -> f32 { self.sqrt().recip() } | |
337 | ||
338 | /// Returns the exponential of the number. | |
339 | #[inline] | |
340 | fn exp(self) -> f32 { | |
341 | unsafe { intrinsics::expf32(self) } | |
342 | } | |
343 | ||
344 | /// Returns 2 raised to the power of the number. | |
345 | #[inline] | |
346 | fn exp2(self) -> f32 { | |
347 | unsafe { intrinsics::exp2f32(self) } | |
348 | } | |
349 | ||
350 | /// Returns the natural logarithm of the number. | |
351 | #[inline] | |
352 | fn ln(self) -> f32 { | |
353 | unsafe { intrinsics::logf32(self) } | |
354 | } | |
355 | ||
356 | /// Returns the logarithm of the number with respect to an arbitrary base. | |
357 | #[inline] | |
358 | fn log(self, base: f32) -> f32 { self.ln() / base.ln() } | |
359 | ||
360 | /// Returns the base 2 logarithm of the number. | |
361 | #[inline] | |
362 | fn log2(self) -> f32 { | |
363 | unsafe { intrinsics::log2f32(self) } | |
364 | } | |
365 | ||
366 | /// Returns the base 10 logarithm of the number. | |
367 | #[inline] | |
368 | fn log10(self) -> f32 { | |
369 | unsafe { intrinsics::log10f32(self) } | |
370 | } | |
371 | ||
372 | /// Converts to degrees, assuming the number is in radians. | |
373 | #[inline] | |
374 | fn to_degrees(self) -> f32 { self * (180.0f32 / consts::PI) } | |
375 | ||
376 | /// Converts to radians, assuming the number is in degrees. | |
377 | #[inline] | |
378 | fn to_radians(self) -> f32 { | |
379 | let value: f32 = consts::PI; | |
380 | self * (value / 180.0f32) | |
381 | } | |
382 | } |