rune/modules/f64.rs
1//! Floating point numbers.
2
3use core::cmp::Ordering;
4use core::num::ParseFloatError;
5
6use crate as rune;
7use crate::alloc::prelude::*;
8use crate::runtime::{VmError, VmErrorKind};
9use crate::{docstring, ContextError, Module};
10
11/// Mathematical constants mirroring Rust's [core::f64::consts].
12pub mod consts {
13 use crate as rune;
14 use crate::{docstring, ContextError, Module};
15
16 /// Mathematical constants mirroring Rust's [core::f64::consts].
17 #[rune::module(::std::f64::consts)]
18 pub fn module() -> Result<Module, ContextError> {
19 let mut m = Module::from_meta(self::module__meta)?;
20
21 m.constant("E", core::f64::consts::E)
22 .build()?
23 .docs(docstring!(
24 /// Euler's number (e)
25 ))?;
26
27 m.constant("FRAC_1_PI", core::f64::consts::FRAC_1_PI)
28 .build()?
29 .docs(docstring!(
30 /// 1 / π
31 ))?;
32 m.constant("FRAC_1_SQRT_2", core::f64::consts::FRAC_1_SQRT_2)
33 .build()?
34 .docs(docstring!(
35 /// 1 / sqrt(2)
36 ))?;
37 m.constant("FRAC_2_PI", core::f64::consts::FRAC_2_PI)
38 .build()?
39 .docs(docstring!(
40 /// 2 / π
41 ))?;
42 m.constant("FRAC_2_SQRT_PI", core::f64::consts::FRAC_2_SQRT_PI)
43 .build()?
44 .docs(docstring!(
45 /// 2 / sqrt(π)
46 ))?;
47
48 m.constant("FRAC_PI_2", core::f64::consts::FRAC_PI_2)
49 .build()?
50 .docs(docstring!(
51 /// π/2
52 ))?;
53 m.constant("FRAC_PI_3", core::f64::consts::FRAC_PI_3)
54 .build()?
55 .docs(docstring!(
56 /// π/3
57 ))?;
58 m.constant("FRAC_PI_4", core::f64::consts::FRAC_PI_4)
59 .build()?
60 .docs(docstring!(
61 /// π/4
62 ))?;
63 m.constant("FRAC_PI_6", core::f64::consts::FRAC_PI_6)
64 .build()?
65 .docs(docstring!(
66 /// π/6
67 ))?;
68 m.constant("FRAC_PI_8", core::f64::consts::FRAC_PI_8)
69 .build()?
70 .docs(docstring!(
71 /// π/8
72 ))?;
73
74 m.constant("LN_2", core::f64::consts::LN_2)
75 .build()?
76 .docs(docstring!(
77 /// ln(2)
78 ))?;
79 m.constant("LN_10", core::f64::consts::LN_10)
80 .build()?
81 .docs(docstring!(
82 /// ln(10)
83 ))?;
84 m.constant("LOG2_10", core::f64::consts::LOG2_10)
85 .build()?
86 .docs(docstring!(
87 /// log<sub>2</sub>(10)
88 ))?;
89 m.constant("LOG2_E", core::f64::consts::LOG2_E)
90 .build()?
91 .docs(docstring!(
92 /// log<sub>2</sub>(e)
93 ))?;
94 m.constant("LOG10_2", core::f64::consts::LOG10_2)
95 .build()?
96 .docs(docstring!(
97 /// log<sub>10</sub>(2)
98 ))?;
99 m.constant("LOG10_E", core::f64::consts::LOG10_E)
100 .build()?
101 .docs(docstring!(
102 /// log<sub>10</sub>(e)
103 ))?;
104
105 m.constant("PI", core::f64::consts::PI)
106 .build()?
107 .docs(docstring!(
108 /// Archimede's constant (π)
109 ))?;
110 m.constant("SQRT_2", core::f64::consts::SQRT_2)
111 .build()?
112 .docs(docstring!(
113 /// sqrt(2)
114 ))?;
115 m.constant("TAU", core::f64::consts::TAU)
116 .build()?
117 .docs(docstring!(
118 /// The full circle constant (τ)
119 ///
120 /// Equal to 2π
121 ))?;
122
123 Ok(m)
124 }
125}
126
127/// Floating point numbers.
128///
129/// This provides methods for computing over and parsing 64-bit floating pointer
130/// numbers.
131#[rune::module(::std::f64)]
132pub fn module() -> Result<Module, ContextError> {
133 let mut m = Module::from_meta(self::module__meta)?;
134
135 m.function_meta(parse)?
136 .deprecated("Use std::string::parse::<f64> instead")?;
137 m.function_meta(is_nan)?;
138 m.function_meta(is_infinite)?;
139 m.function_meta(is_finite)?;
140 m.function_meta(is_subnormal)?;
141 m.function_meta(is_normal)?;
142 m.function_meta(max__meta)?;
143 m.function_meta(min__meta)?;
144 m.function_meta(to_string)?;
145
146 #[cfg(feature = "std")]
147 {
148 m.function_meta(abs)?;
149 m.function_meta(acos)?;
150 m.function_meta(asin)?;
151 m.function_meta(atan)?;
152 m.function_meta(atan2)?;
153 m.function_meta(cbrt)?;
154 m.function_meta(ceil)?;
155 m.function_meta(clamp)?;
156 m.function_meta(cos)?;
157 m.function_meta(div_euclid)?;
158 m.function_meta(exp)?;
159 m.function_meta(exp2)?;
160 m.function_meta(floor)?;
161 m.function_meta(ln)?;
162 m.function_meta(log)?;
163 m.function_meta(log10)?;
164 m.function_meta(log2)?;
165 m.function_meta(powf)?;
166 m.function_meta(powi)?;
167 m.function_meta(rem_euclid)?;
168 m.function_meta(round)?;
169 m.function_meta(sin)?;
170 m.function_meta(sqrt)?;
171 m.function_meta(tan)?;
172 }
173 m.function_meta(to_integer)?;
174 m.function_meta(to_degrees)?;
175 m.function_meta(to_radians)?;
176
177 m.function_meta(clone__meta)?;
178 m.implement_trait::<f64>(rune::item!(::std::clone::Clone))?;
179
180 m.function_meta(partial_eq__meta)?;
181 m.implement_trait::<f64>(rune::item!(::std::cmp::PartialEq))?;
182
183 m.function_meta(eq__meta)?;
184 m.implement_trait::<f64>(rune::item!(::std::cmp::Eq))?;
185
186 m.function_meta(partial_cmp__meta)?;
187 m.implement_trait::<f64>(rune::item!(::std::cmp::PartialOrd))?;
188
189 m.function_meta(cmp__meta)?;
190 m.implement_trait::<f64>(rune::item!(::std::cmp::Ord))?;
191
192 m.constant("EPSILON", f64::EPSILON)
193 .build()?
194 .docs(docstring!(
195 /// [Machine epsilon] value for `f64`.
196 ///
197 /// This is the difference between `1.0` and the next larger representable number.
198 ///
199 /// Equal to 2<sup>1 - MANTISSA_DIGITS</sup>.
200 ///
201 /// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon
202 ))?;
203 m.constant("MIN", f64::MIN).build()?.docs(docstring!(
204 /// The smallest finite `f64` value.
205 ///
206 /// Equal to -[`MAX`].
207 ///
208 /// [`MAX`]: f64::MAX
209 ))?;
210 m.constant("MAX", f64::MAX).build()?.docs(docstring!(
211 /// Largest finite `f64` value.
212 ///
213 /// Equal to
214 /// (1 - 2<sup>-MANTISSA_DIGITS</sup>) 2<sup>[`MAX_EXP`]</sup>.
215 ///
216 /// [`MAX_EXP`]: f64::MAX_EXP
217 ))?;
218 m.constant("MIN_POSITIVE", f64::MIN_POSITIVE)
219 .build()?
220 .docs(docstring!(
221 /// Smallest positive normal `f64` value.
222 ///
223 /// Equal to 2<sup>[`MIN_EXP`] - 1</sup>.
224 ///
225 /// [`MIN_EXP`]: f64::MIN_EXP
226 ))?;
227 m.constant("MIN_EXP", f64::MIN_EXP)
228 .build()?
229 .docs(docstring!(
230 /// One greater than the minimum possible *normal* power of 2 exponent
231 /// for a significand bounded by 1 ≤ x < 2 (i.e. the IEEE definition).
232 ///
233 /// This corresponds to the exact minimum possible *normal* power of 2 exponent
234 /// for a significand bounded by 0.5 ≤ x < 1 (i.e. the C definition).
235 /// In other words, all normal numbers representable by this type are
236 /// greater than or equal to 0.5 × 2<sup><i>MIN_EXP</i></sup>.
237 ))?;
238 m.constant("MAX_EXP", f64::MAX_EXP)
239 .build()?
240 .docs(docstring!(
241 /// One greater than the maximum possible power of 2 exponent
242 /// for a significand bounded by 1 ≤ x < 2 (i.e. the IEEE definition).
243 ///
244 /// This corresponds to the exact maximum possible power of 2 exponent
245 /// for a significand bounded by 0.5 ≤ x < 1 (i.e. the C definition).
246 /// In other words, all numbers representable by this type are
247 /// strictly less than 2<sup><i>MAX_EXP</i></sup>.
248 ))?;
249 m.constant("MIN_10_EXP", f64::MIN_10_EXP)
250 .build()?
251 .docs(docstring!(
252 /// Minimum <i>x</i> for which 10<sup><i>x</i></sup> is normal.
253 ///
254 /// Equal to ceil(log<sub>10</sub> [`MIN_POSITIVE`]).
255 ///
256 /// [`MIN_POSITIVE`]: f64::MIN_POSITIVE
257 ))?;
258 m.constant("MAX_10_EXP", f64::MAX_10_EXP)
259 .build()?
260 .docs(docstring!(
261 /// Maximum <i>x</i> for which 10<sup><i>x</i></sup> is normal.
262 ///
263 /// Equal to floor(log<sub>10</sub> [`MAX`]).
264 ///
265 /// [`MAX`]: f64::MAX
266 ))?;
267 m.constant("NAN", f64::NAN).build()?.docs(docstring!(
268 /// Not a number (NaN).
269 ///
270 ///
271 /// Note that IEEE 754 doesn't define just a single NaN value; a plethora of bit patterns
272 /// are considered to be NaN. Furthermore, the standard makes a difference between a
273 /// "signaling" and a "quiet" NaN, and allows inspecting its "payload" (the unspecified
274 /// bits in the bit pattern) and its sign. See the [Rust documentation of NaN bit
275 /// patterns](https://doc.rust-lang.org/core/primitive.f32.html#nan-bit-patterns) for more
276 /// info.
277 ///
278 /// This constant is guaranteed to be a quiet NaN (on targets that follow the Rust assumptions
279 /// that the quiet/signaling bit being set to 1 indicates a quiet NaN). Beyond that, nothing is
280 /// guaranteed about the specific bit pattern chosen here: both payload and sign are arbitrary.
281 /// The concrete bit pattern may change across Rust versions and target platforms.
282 ))?;
283 m.constant("INFINITY", f64::INFINITY)
284 .build()?
285 .docs(docstring!(
286 /// Positive infinity (∞).
287 ))?;
288 m.constant("NEG_INFINITY", f64::NEG_INFINITY)
289 .build()?
290 .docs(docstring!(
291 /// Negative infinity (−∞).
292 ))?;
293
294 Ok(m)
295}
296
297#[rune::function]
298fn parse(s: &str) -> Result<f64, ParseFloatError> {
299 str::parse::<f64>(s)
300}
301
302/// Convert a float to a an integer.
303///
304/// # Examples
305///
306/// ```rune
307/// let n = 7.0_f64.to::<i64>();
308/// assert_eq!(n, 7);
309/// ```
310#[rune::function(instance, path = to::<i64>)]
311fn to_integer(value: f64) -> i64 {
312 value as i64
313}
314
315/// Converts radians to degrees.
316///
317/// # Examples
318///
319/// ```rune
320/// let abs_difference = (std::f64::consts::PI.to_degrees() - 180.0).abs();
321/// assert!(abs_difference < 1e-10);
322/// ```
323#[rune::function(instance)]
324fn to_degrees(this: f64) -> f64 {
325 this.to_degrees()
326}
327
328/// Converts degrees to radians.
329///
330/// # Examples
331///
332/// ```rune
333/// let abs_difference = (180.0.to_radians() - std::f64::consts::PI).abs();
334/// assert!(abs_difference < 1e-10);
335/// ```
336#[rune::function(instance)]
337fn to_radians(this: f64) -> f64 {
338 this.to_radians()
339}
340
341/// Returns `true` if this value is NaN.
342///
343/// # Examples
344///
345/// ```rune
346/// let nan = f64::NAN;
347/// let f = 7.0_f64;
348///
349/// assert!(nan.is_nan());
350/// assert!(!f.is_nan());
351/// ```
352#[rune::function(instance)]
353fn is_nan(this: f64) -> bool {
354 this.is_nan()
355}
356
357/// Returns `true` if this value is positive infinity or negative infinity, and
358/// `false` otherwise.
359///
360/// # Examples
361///
362/// ```rune
363/// let f = 7.0f64;
364/// let inf = f64::INFINITY;
365/// let neg_inf = f64::NEG_INFINITY;
366/// let nan = f64::NAN;
367///
368/// assert!(!f.is_infinite());
369/// assert!(!nan.is_infinite());
370///
371/// assert!(inf.is_infinite());
372/// assert!(neg_inf.is_infinite());
373/// ```
374#[rune::function(instance)]
375fn is_infinite(this: f64) -> bool {
376 this.is_infinite()
377}
378
379/// Returns `true` if this number is neither infinite nor NaN.
380///
381/// # Examples
382///
383/// ```rune
384/// let f = 7.0f64;
385/// let inf = f64::INFINITY;
386/// let neg_inf = f64::NEG_INFINITY;
387/// let nan = f64::NAN;
388///
389/// assert!(f.is_finite());
390///
391/// assert!(!nan.is_finite());
392/// assert!(!inf.is_finite());
393/// assert!(!neg_inf.is_finite());
394/// ```
395#[rune::function(instance)]
396fn is_finite(this: f64) -> bool {
397 this.is_finite()
398}
399
400/// Returns `true` if the number is [subnormal].
401///
402/// # Examples
403///
404/// ```rune
405/// let min = f64::MIN_POSITIVE; // 2.2250738585072014e-308_f64
406/// let max = f64::MAX;
407/// let lower_than_min = 1.0e-308_f64;
408/// let zero = 0.0_f64;
409///
410/// assert!(!min.is_subnormal());
411/// assert!(!max.is_subnormal());
412///
413/// assert!(!zero.is_subnormal());
414/// assert!(!f64::NAN.is_subnormal());
415/// assert!(!f64::INFINITY.is_subnormal());
416/// // Values between `0` and `min` are Subnormal.
417/// assert!(lower_than_min.is_subnormal());
418/// ```
419///
420/// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
421#[rune::function(instance)]
422fn is_subnormal(this: f64) -> bool {
423 this.is_subnormal()
424}
425
426/// Returns `true` if the number is neither zero, infinite, [subnormal], or NaN.
427///
428/// # Examples
429///
430/// ```rune
431/// let min = f64::MIN_POSITIVE; // 2.2250738585072014e-308f64
432/// let max = f64::MAX;
433/// let lower_than_min = 1.0e-308_f64;
434/// let zero = 0.0f64;
435///
436/// assert!(min.is_normal());
437/// assert!(max.is_normal());
438///
439/// assert!(!zero.is_normal());
440/// assert!(!f64::NAN.is_normal());
441/// assert!(!f64::INFINITY.is_normal());
442/// // Values between `0` and `min` are Subnormal.
443/// assert!(!lower_than_min.is_normal());
444/// ```
445/// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
446#[rune::function(instance)]
447fn is_normal(this: f64) -> bool {
448 this.is_normal()
449}
450
451/// Returns the maximum of the two numbers, ignoring NaN.
452///
453/// If one of the arguments is NaN, then the other argument is returned. This
454/// follows the IEEE 754-2008 semantics for maxNum, except for handling of
455/// signaling NaNs; this function handles all NaNs the same way and avoids
456/// maxNum's problems with associativity. This also matches the behavior of
457/// libm’s fmax.
458///
459/// # Examples
460///
461/// ```rune
462/// let x = 1.0_f64;
463/// let y = 2.0_f64;
464///
465/// assert_eq!(x.max(y), y);
466/// ```
467#[rune::function(keep, instance, protocol = MAX)]
468fn max(this: f64, other: f64) -> f64 {
469 this.max(other)
470}
471
472/// Returns the minimum of the two numbers, ignoring NaN.
473///
474/// If one of the arguments is NaN, then the other argument is returned. This
475/// follows the IEEE 754-2008 semantics for minNum, except for handling of
476/// signaling NaNs; this function handles all NaNs the same way and avoids
477/// minNum's problems with associativity. This also matches the behavior of
478/// libm’s fmin.
479///
480/// # Examples
481///
482/// ```rune
483/// let x = 1.0_f64;
484/// let y = 2.0_f64;
485///
486/// assert_eq!(x.min(y), x);
487/// ```
488#[rune::function(keep, instance, protocol = MIN)]
489fn min(this: f64, other: f64) -> f64 {
490 this.min(other)
491}
492
493/// Returns the square root of a number.
494///
495/// Returns NaN if `self` is a negative number other than `-0.0`.
496///
497/// # Examples
498///
499/// ```rune
500/// let positive = 4.0_f64;
501/// let negative = -4.0_f64;
502/// let negative_zero = -0.0_f64;
503///
504/// let abs_difference = (positive.sqrt() - 2.0).abs();
505///
506/// assert!(abs_difference < 1e-10);
507/// assert!(negative.sqrt().is_nan());
508/// assert!(negative_zero.sqrt() == negative_zero);
509/// ```
510#[rune::function(instance)]
511#[cfg(feature = "std")]
512fn sqrt(this: f64) -> f64 {
513 this.sqrt()
514}
515
516/// Computes the absolute value of `self`.
517///
518/// # Examples
519///
520/// ```rune
521/// let x = 3.5_f64;
522/// let y = -3.5_f64;
523///
524/// let abs_difference_x = (x.abs() - x).abs();
525/// let abs_difference_y = (y.abs() - (-y)).abs();
526///
527/// assert!(abs_difference_x < 1e-10);
528/// assert!(abs_difference_y < 1e-10);
529///
530/// assert!(f64::NAN.abs().is_nan());
531/// ```
532#[rune::function(instance)]
533#[cfg(feature = "std")]
534fn abs(this: f64) -> f64 {
535 this.abs()
536}
537
538/// Raises a number to a floating point power.
539///
540/// # Examples
541///
542/// ```rune
543/// let x = 2.0_f64;
544/// let abs_difference = (x.powf(2.0) - (x * x)).abs();
545///
546/// assert!(abs_difference < 1e-10);
547/// ```
548#[rune::function(instance)]
549#[cfg(feature = "std")]
550fn powf(this: f64, other: f64) -> f64 {
551 this.powf(other)
552}
553
554/// Raises a number to an integer power.
555///
556/// Using this function is generally faster than using `powf`. It might have a
557/// different sequence of rounding operations than `powf`, so the results are
558/// not guaranteed to agree.
559///
560/// # Examples
561///
562/// ```rune
563/// let x = 2.0_f64;
564/// let abs_difference = (x.powi(2) - (x * x)).abs();
565///
566/// assert!(abs_difference < 1e-10);
567/// ```
568#[rune::function(instance)]
569#[cfg(feature = "std")]
570fn powi(this: f64, other: i32) -> f64 {
571 this.powi(other)
572}
573
574/// Returns the largest integer less than or equal to `self`.
575///
576/// # Examples
577///
578/// ```rune
579/// let f = 3.7_f64;
580/// let g = 3.0_f64;
581/// let h = -3.7_f64;
582///
583/// assert!(f.floor() == 3.0);
584/// assert!(g.floor() == 3.0);
585/// assert!(h.floor() == -4.0);
586/// ```
587#[rune::function(instance)]
588#[cfg(feature = "std")]
589fn floor(this: f64) -> f64 {
590 this.floor()
591}
592
593/// Returns the smallest integer greater than or equal to `self`.
594///
595/// # Examples
596///
597/// ```rune
598/// let f = 3.01_f64;
599/// let g = 4.0_f64;
600///
601/// assert_eq!(f.ceil(), 4.0);
602/// assert_eq!(g.ceil(), 4.0);
603/// ```
604#[rune::function(instance)]
605#[cfg(feature = "std")]
606fn ceil(this: f64) -> f64 {
607 this.ceil()
608}
609
610/// Returns the nearest integer to `self`. If a value is half-way between two
611/// integers, round away from `0.0`.
612///
613/// # Examples
614///
615/// ```rune
616/// let f = 3.3_f64;
617/// let g = -3.3_f64;
618/// let h = -3.7_f64;
619/// let i = 3.5_f64;
620/// let j = 4.5_f64;
621///
622/// assert_eq!(f.round(), 3.0);
623/// assert_eq!(g.round(), -3.0);
624/// assert_eq!(h.round(), -4.0);
625/// assert_eq!(i.round(), 4.0);
626/// assert_eq!(j.round(), 5.0);
627/// ```
628#[rune::function(instance)]
629#[cfg(feature = "std")]
630fn round(this: f64) -> f64 {
631 this.round()
632}
633
634/// Clone a `f64`.
635///
636/// Note that since the type is copy, cloning has the same effect as assigning
637/// it.
638///
639/// # Examples
640///
641/// ```rune
642/// let a = 5.0;
643/// let b = a;
644/// let c = a.clone();
645///
646/// a += 1.0;
647///
648/// assert_eq!(a, 6.0);
649/// assert_eq!(b, 5.0);
650/// assert_eq!(c, 5.0);
651/// ```
652#[rune::function(keep, instance, protocol = CLONE)]
653#[inline]
654fn clone(this: f64) -> f64 {
655 this
656}
657
658/// Test two floats for partial equality.
659///
660/// # Examples
661///
662/// ```rune
663/// assert!(5.0 == 5.0);
664/// assert!(5.0 != 10.0);
665/// assert!(10.0 != 5.0);
666/// assert!(10.0 != f64::NAN);
667/// assert!(f64::NAN != f64::NAN);
668/// ```
669#[rune::function(keep, instance, protocol = PARTIAL_EQ)]
670#[inline]
671fn partial_eq(this: f64, rhs: f64) -> bool {
672 this.eq(&rhs)
673}
674
675/// Test two floats for total equality.
676///
677/// # Examples
678///
679/// ```rune
680/// use std::ops::eq;
681///
682/// assert_eq!(eq(5.0, 5.0), true);
683/// assert_eq!(eq(5.0, 10.0), false);
684/// assert_eq!(eq(10.0, 5.0), false);
685/// ```
686#[rune::function(keep, instance, protocol = EQ)]
687#[inline]
688fn eq(this: f64, rhs: f64) -> Result<bool, VmError> {
689 let Some(ordering) = this.partial_cmp(&rhs) else {
690 return Err(VmError::new(VmErrorKind::IllegalFloatComparison {
691 lhs: this,
692 rhs,
693 }));
694 };
695
696 Ok(matches!(ordering, Ordering::Equal))
697}
698
699/// Perform a partial ordered comparison between two floats.
700///
701/// # Examples
702///
703/// ```rune
704/// use std::cmp::Ordering;
705/// use std::ops::partial_cmp;
706///
707/// assert_eq!(partial_cmp(5.0, 10.0), Some(Ordering::Less));
708/// assert_eq!(partial_cmp(10.0, 5.0), Some(Ordering::Greater));
709/// assert_eq!(partial_cmp(5.0, 5.0), Some(Ordering::Equal));
710/// assert_eq!(partial_cmp(5.0, f64::NAN), None);
711/// ```
712#[rune::function(keep, instance, protocol = PARTIAL_CMP)]
713#[inline]
714fn partial_cmp(this: f64, rhs: f64) -> Option<Ordering> {
715 this.partial_cmp(&rhs)
716}
717
718/// Perform a totally ordered comparison between two floats.
719///
720/// # Examples
721///
722/// ```rune
723/// use std::cmp::Ordering;
724/// use std::ops::cmp;
725///
726/// assert_eq!(cmp(5.0, 10.0), Ordering::Less);
727/// assert_eq!(cmp(10.0, 5.0), Ordering::Greater);
728/// assert_eq!(cmp(5.0, 5.0), Ordering::Equal);
729/// ```
730#[rune::function(keep, instance, protocol = CMP)]
731#[inline]
732fn cmp(this: f64, rhs: f64) -> Result<Ordering, VmError> {
733 let Some(ordering) = this.partial_cmp(&rhs) else {
734 return Err(VmError::new(VmErrorKind::IllegalFloatComparison {
735 lhs: this,
736 rhs,
737 }));
738 };
739
740 Ok(ordering)
741}
742
743/// Computes the arccosine of a number.
744///
745/// Return value is in radians in the range [0, pi] or NaN if the number is outside the range [-1,
746/// 1].
747///
748/// # Examples
749///
750/// ```rune
751/// let f = std::f64::consts::FRAC_PI_4;
752///
753/// // acos(cos(pi/4))
754/// let abs_difference = (f.cos().acos() - std::f64::consts::FRAC_PI_4).abs();
755/// assert!(abs_difference < 1e-10);
756/// ```
757#[rune::function(instance)]
758#[cfg(feature = "std")]
759fn acos(this: f64) -> f64 {
760 this.acos()
761}
762
763/// Computes the arcsine of a number.
764///
765/// Return value is in radians in the range [-pi/2, pi/2] or NaN if the number is outside the range
766/// [-1, 1].
767///
768/// # Examples
769///
770/// ```rune
771/// let f = std::f64::consts::FRAC_PI_2;
772///
773/// // asin(sin(pi/2))
774/// let abs_difference = (f.sin().asin() - std::f64::consts::FRAC_PI_2).abs();
775/// assert!(abs_difference < 1e-7);
776/// ```
777#[rune::function(instance)]
778#[cfg(feature = "std")]
779fn asin(this: f64) -> f64 {
780 this.asin()
781}
782
783/// Computes the arctangent of a number.
784///
785/// Return value is in radians in the range [-pi/2, pi/2];
786///
787/// # Examples
788///
789/// ```rune
790/// let f = 1.0;
791///
792/// // atan(tan(1))
793/// let abs_difference = (f.tan().atan() - 1.0).abs();
794/// assert!(abs_difference < 1e-10);
795/// ```
796#[rune::function(instance)]
797#[cfg(feature = "std")]
798fn atan(this: f64) -> f64 {
799 this.atan()
800}
801
802/// Computes the four quadrant arctangent of self (y) and other (x) in radians.
803///
804/// * `x = 0`, `y = 0`: `0`
805/// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
806/// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
807/// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
808///
809/// # Examples
810///
811/// ```rune
812/// // Positive angles measured counter-clockwise
813/// // from positive x axis
814/// // -pi/4 radians (45 deg clockwise)
815/// let x1 = 3.0;
816/// let y1 = -3.0;
817///
818/// // 3pi/4 radians (135 deg counter-clockwise)
819/// let x2 = -3.0;
820/// let y2 = 3.0;
821///
822/// let abs_difference_1 = (y1.atan2(x1) - (-std::f64::consts::FRAC_PI_4)).abs();
823/// let abs_difference_2 = (y2.atan2(x2) - (3.0 * std::f64::consts::FRAC_PI_4)).abs();
824///
825/// assert!(abs_difference_1 < 1e-10);
826/// assert!(abs_difference_2 < 1e-10);
827/// ```
828#[rune::function(instance)]
829#[cfg(feature = "std")]
830fn atan2(this: f64, other: f64) -> f64 {
831 this.atan2(other)
832}
833
834/// Returns the cube root of a number.
835///
836/// # Examples
837///
838/// ```rune
839/// let x = 8.0_f64;
840///
841/// // x^(1/3) - 2 == 0
842/// let abs_difference = (x.cbrt() - 2.0).abs();
843/// assert!(abs_difference < 1e-10);
844/// ```
845#[rune::function(instance)]
846#[cfg(feature = "std")]
847fn cbrt(this: f64) -> f64 {
848 this.cbrt()
849}
850
851/// Computes the cosine of a number (in radians).
852///
853/// # Examples
854///
855/// ```rune
856/// let x = 2.0 * std::f64::consts::PI;
857///
858/// let abs_difference = (x.cos() - 1.0).abs();
859/// assert!(abs_difference < 1e-10);
860/// ```
861#[rune::function(instance)]
862#[cfg(feature = "std")]
863fn cos(this: f64) -> f64 {
864 this.cos()
865}
866
867/// Restrict a value to a certain interval unless it is NaN.
868///
869/// Returns `max` if `self` is greater than `max`, and `min` if `self` is less than `min`.
870/// Otherwise this returns `self`.
871///
872/// Note that this function returns NaN if the initial value was NaN as well.
873///
874/// # Panics
875///
876/// Panics if `min > max`, `min` is NaN, or `max` is NaN.
877///
878/// # Examples
879///
880/// ```rune
881/// assert!((-3.0f64).clamp(-2.0, 1.0) == -2.0);
882/// assert!((0.0f64).clamp(-2.0, 1.0) == 0.0);
883/// assert!((2.0f64).clamp(-2.0, 1.0) == 1.0);
884/// assert!((f64::NAN).clamp(-2.0, 1.0).is_nan());
885/// ```
886#[rune::function(instance)]
887#[cfg(feature = "std")]
888fn clamp(this: f64, min: f64, max: f64) -> f64 {
889 this.clamp(min, max)
890}
891
892/// Calculates Euclidean division, the matching method for rem_euclid.
893///
894/// This computes the integer `n` such that `self = n * rhs + self.rem_euclid(rhs)`. In other
895/// words, the result is `self / rhs` rounded to the integer `n` such that `self >= n * rhs`.
896///
897/// # Examples
898///
899/// ```rune
900/// let a = 7.0;
901/// let b = 4.0;
902/// assert_eq!(a.div_euclid(b), 1.0); // 7.0 > 4.0 * 1.0
903/// assert_eq!((-a).div_euclid(b), -2.0); // -7.0 >= 4.0 * -2.0
904/// assert_eq!(a.div_euclid(-b), -1.0); // 7.0 >= -4.0 * -1.0
905/// assert_eq!((-a).div_euclid(-b), 2.0); // -7.0 >= -4.0 * 2.0
906/// ```
907#[rune::function(instance)]
908#[cfg(feature = "std")]
909fn div_euclid(this: f64, rhs: f64) -> f64 {
910 this.div_euclid(rhs)
911}
912
913/// Computes the least nonnegative remainder of `self (mod rhs)`.
914///
915/// In particular, the return value `r` satisfies `0.0 <= r < rhs.abs()` in most cases. However,
916/// due to a floating point round-off error it can result in `r == rhs.abs()`, violating the
917/// mathematical definition, if `self` is much smaller than `rhs.abs()` in magnitude and `self <
918/// 0.0`. This result is not an element of the function’s codomain, but it is the closest floating
919/// point number in the real numbers and thus fulfills the property `self == self.div_euclid(rhs) *
920/// rhs + self.rem_euclid(rhs)` approximately.
921///
922/// # Examples
923///
924/// ```rune
925/// let a = 7.0;
926/// let b = 4.0;
927/// assert_eq!(a.rem_euclid(b), 3.0);
928/// assert_eq!((-a).rem_euclid(b), 1.0);
929/// assert_eq!(a.rem_euclid(-b), 3.0);
930/// assert_eq!((-a).rem_euclid(-b), 1.0);
931/// // limitation due to round-off error
932/// assert!((-f64::EPSILON).rem_euclid(3.0) != 0.0);
933/// ```
934#[rune::function(instance)]
935#[cfg(feature = "std")]
936fn rem_euclid(this: f64, rhs: f64) -> f64 {
937 this.rem_euclid(rhs)
938}
939
940/// Returns `e^(self)`, (the exponential function).
941///
942/// # Examples
943///
944/// ```rune
945/// let one = 1.0_f64;
946/// // e^1
947/// let e = one.exp();
948///
949/// // ln(e) - 1 == 0
950/// let abs_difference = (e.ln() - 1.0).abs();
951/// assert!(abs_difference < 1e-10);
952/// ```
953#[rune::function(instance)]
954#[cfg(feature = "std")]
955fn exp(this: f64) -> f64 {
956 this.exp()
957}
958
959/// Returns `2^(self)`.
960///
961/// Examples
962///
963/// ```rune
964/// let f = 2.0_f64;
965///
966/// // 2^2 - 4 == 0
967/// let abs_difference = (f.exp2() - 4.0).abs();
968/// assert!(abs_difference < 1e-10);
969/// ```
970#[rune::function(instance)]
971#[cfg(feature = "std")]
972fn exp2(this: f64) -> f64 {
973 this.exp2()
974}
975
976/// Returns the natural logarithm of the number.
977///
978/// This returns NaN when the number is negative, and negative infinity when number is zero.
979///
980/// # Examples
981///
982/// ```rune
983/// let one = 1.0;
984/// // e^1
985/// let e = one.exp();
986///
987/// // ln(e) - 1 == 0
988/// let abs_difference = (e.ln() - 1.0).abs();
989/// assert!(abs_difference < 1e-10);
990/// ```
991#[rune::function(instance)]
992#[cfg(feature = "std")]
993fn ln(this: f64) -> f64 {
994 this.ln()
995}
996
997/// Returns the logarithm of the number with respect to an arbitrary base.
998///
999/// This returns NaN when the number is negative, and negative infinity when number is zero.
1000///
1001/// The result might not be correctly rounded owing to implementation details; `self.log2()` can
1002/// produce more accurate results for base 2, and `self.log10()` can produce more accurate results
1003/// for base 10.
1004///
1005/// # Examples
1006///
1007/// ```rune
1008/// let twenty_five = 25.0_f64;
1009///
1010/// // log5(25) - 2 == 0
1011/// let abs_difference = (twenty_five.log(5.0) - 2.0).abs();
1012/// assert!(abs_difference < 1e-10);
1013/// ```
1014#[rune::function(instance)]
1015#[cfg(feature = "std")]
1016fn log(this: f64, base: f64) -> f64 {
1017 this.log(base)
1018}
1019
1020/// Returns the base 2 logarithm of the number.
1021///
1022/// This returns NaN when the number is negative, and negative infinity when number is zero.
1023///
1024/// # Examples
1025///
1026/// ```rune
1027/// let four = 4.0_f64;
1028///
1029/// // log2(4) - 2 == 0
1030/// let abs_difference = (four.log2() - 2.0).abs();
1031///
1032/// assert!(abs_difference < 1e-10);
1033/// ```
1034///
1035/// Non-positive values:
1036///
1037/// ```rune
1038/// assert_eq!(0_f64.log2(), f64::NEG_INFINITY);
1039/// assert!((-42_f64).log2().is_nan());
1040/// ```
1041#[rune::function(instance)]
1042#[cfg(feature = "std")]
1043fn log2(this: f64) -> f64 {
1044 this.log2()
1045}
1046
1047/// Returns the base 10 logarithm of the number.
1048///
1049/// This returns NaN when the number is negative, and negative infinity when number is zero.
1050///
1051/// # Examples
1052///
1053/// ```rune
1054/// let hundred = 100.0_f64;
1055///
1056/// // log10(100) - 2 == 0
1057/// let abs_difference = (hundred.log10() - 2.0).abs();
1058/// assert!(abs_difference < 1e-10);
1059/// ```
1060#[rune::function(instance)]
1061#[cfg(feature = "std")]
1062fn log10(this: f64) -> f64 {
1063 this.log10()
1064}
1065
1066/// Computes the sine of a number (in radians).
1067///
1068/// # Examples
1069///
1070/// ```rune
1071/// let x = std::f64::consts::FRAC_PI_2;
1072///
1073/// let abs_difference = (x.sin() - 1.0).abs();
1074/// assert!(abs_difference < 1e-10);
1075/// ```
1076#[rune::function(instance)]
1077#[cfg(feature = "std")]
1078fn sin(this: f64) -> f64 {
1079 this.sin()
1080}
1081
1082/// Computes the tangent of a number (in radians).
1083///
1084/// # Examples
1085///
1086/// ```rune
1087/// let x = std::f64::consts::FRAC_PI_4;
1088/// let abs_difference = (x.tan() - 1.0).abs();
1089/// assert!(abs_difference < 1e-14);
1090/// ```
1091#[rune::function(instance)]
1092#[cfg(feature = "std")]
1093fn tan(this: f64) -> f64 {
1094 this.tan()
1095}
1096
1097/// Returns the number as a string.
1098///
1099/// # Examples
1100///
1101/// Basic usage:
1102///
1103/// ```rune
1104/// assert_eq!(1.5.to_string(), "1.5");
1105/// assert_eq!((-0.0).to_string(), "-0");
1106/// ```
1107#[rune::function(instance)]
1108#[inline]
1109fn to_string(this: f64) -> crate::alloc::Result<crate::alloc::String> {
1110 this.try_to_string()
1111}