mathx/
math.rs

1
2use core::ops::Range;
3
4/// A "static" structure used to compute math functions. Since `f32` gets a lot of it's
5/// functions stripped away when using `no_std`, you can use this structure to regain
6/// those functions. It will also work the same even if you don't use it for `no_std`.
7pub struct Math;
8
9// Constants
10impl Math {
11	pub const PI: f32 = 3.14159265359;
12	pub const PI_OVER_2: f32 = 1.570796326;
13	pub const PI_OVER_4: f32 = 0.785398163;
14	pub const TWO_PI: f32 = 6.28318530718;
15	pub const E: f32 = 2.71828182845;
16	pub const DEG_TO_RAD: f32 = 0.01745329251;
17	pub const RAD_TO_DEG: f32 = 57.2957795131;
18	pub const LN2: f32 = 0.69314718056;
19	pub const LN10: f32 = 2.30258509299;
20}
21
22// Public Functions
23impl Math {
24	/// Gets the absolute value of the number
25	/// - **value**: The number to get the absolute value from
26	/// 
27	/// **Returns**: Returns the absolute value of the number
28	/// #### Examples
29	/// ```
30	/// # use mathx::Math;
31	/// let value = Math::abs(10.0);
32	/// assert_eq!(10.0, value);
33	/// let value = Math::abs(-10.0);
34	/// assert_eq!(10.0, value);
35	/// let value = Math::abs(-0.0);
36	/// assert_eq!(0.0, value);
37	/// ```
38	pub fn abs(value: f32) -> f32 {
39		#[cfg(not(feature = "no_std"))] { value.abs() }
40		#[cfg(feature = "no_std")] {
41			if value < 0.0 { -value } else { value }
42		}
43	}
44	
45	/// Gets the absolute value of the number
46	/// - **value**: The number to get the absolute value from
47	/// 
48	/// **Returns**: Returns the absolute value of the number
49	/// #### Examples
50	/// ```
51	/// # use mathx::Math;
52	/// let value = Math::abs_i32(10);
53	/// assert_eq!(10, value);
54	/// let value = Math::abs_i32(-10);
55	/// assert_eq!(10, value);
56	/// let value = Math::abs_i32(-0);
57	/// assert_eq!(0, value);
58	/// ```
59	pub fn abs_i32(value: i32) -> i32 {
60		#[cfg(not(feature = "no_std"))] { value.abs() }
61		#[cfg(feature = "no_std")] {
62			if value < 0 { -value } else { value }
63		}
64	}
65	
66	/// Finds if the two floating point numbers are approximately close to each other. Checks with epsilon = 0.000001
67	/// - **a**: The first number to check with
68	/// - **b**: The second number to check with
69	/// 
70	/// **Returns**: Returns true if the two values are approximately close to each other
71	/// #### Examples
72	/// ```
73	/// # use mathx::Math;
74	/// assert!(Math::approx(1.20000001, 1.2));
75	/// ```
76	pub fn approx(a: f32, b: f32) -> bool {
77		Math::abs(a - b) < 0.000001
78	}
79	
80	/// Finds if the two floating point numbers are approximately close to each other, provided the epsilon
81	/// - **a**: The first number to check with
82	/// - **b**: The second number to check with
83	/// - **epsilon**: The epsilon (smallest possible difference between numbers) to check with
84	/// 
85	/// **Returns**: Returns true if the two values are approximately close to each other
86	/// #### Examples
87	/// ```
88	/// # use mathx::Math;
89	/// assert!(Math::approx_epsilon(1.2001, 1.2, 0.001));
90	/// ```
91	pub fn approx_epsilon(a: f32, b: f32, epsilon: f32) -> bool {
92		Math::abs(a - b) < epsilon
93	}
94	
95	/// Computes the arc cosine (a.k.a. inverse cosine) with the provided value
96	/// - **value**: The value to compute the arc cosine with, must be within -1 and 1
97	/// 
98	/// **Returns**: Returns the angle at which the value exists in radians,
99	/// returns `NaN` if the value provided is less than -1 or greater than 1
100	/// #### Examples
101	/// ```
102	/// # use mathx::{Math,assert_range};
103	/// let value = Math::acos(0.0);
104	/// assert_range!(Math::PI_OVER_2, value);
105	/// let value = Math::acos(1.0);
106	/// assert_range!(0.0, value);
107	/// let value = Math::acos(-1.0);
108	/// assert_range!(Math::PI, value);
109	/// let value = Math::acos(0.707106781);
110	/// assert_range!(Math::PI_OVER_4, value);
111	/// let value = Math::acos(0.540302306);
112	/// assert_range!(1.0, value);
113	/// let value = Math::acos(2.0);
114	/// assert!(value.is_nan());
115	/// let value = Math::acos(-1.001);
116	/// assert!(value.is_nan());
117	/// ```
118	pub fn acos(value: f32) -> f32 {
119		#[cfg(not(feature = "no_std"))] { value.acos() }
120		#[cfg(feature = "no_std")] {
121			if value < -1.0 || value > 1.0 { return f32::NAN; }
122			
123			let negate = if value <= -0.0 { 1.0 } else { 0.0 };
124			let value = Math::abs(value);
125			let mut angle = -0.0187293;
126			
127			angle *= value;
128			angle += 0.0742610;
129			angle *= value;
130			angle -= 0.2121144;
131			angle *= value;
132			angle += Math::PI_OVER_2;
133			angle *= Math::sqrt(1.0 - value);
134			angle -= 2.0 * negate * angle;
135			
136			return negate * Math::PI + angle;
137		}
138	}
139	
140	/// Computes the arc cosine (a.k.a. inverse cosine) with the provided value
141	/// - **value**: The value to compute the arc cosine with, must be within -1 and 1
142	/// 
143	/// **Returns**: Returns the angle at which the value exists in degrees,
144	/// returns `NaN` if the value provided is less than -1 or greater than 1
145	/// #### Examples
146	/// ```
147	/// # use mathx::{Math,assert_range};
148	/// let value = Math::acos_deg(0.0);
149	/// assert_range!(90.0, value);
150	/// let value = Math::acos_deg(1.0);
151	/// assert_range!(0.0, value);
152	/// let value = Math::acos_deg(-1.0);
153	/// assert_range!(180.0, value);
154	/// let value = Math::acos_deg(0.707106781);
155	/// assert_range!(45.0, value, 0.005);
156	/// let value = Math::acos_deg(0.540302306);
157	/// assert_range!(57.29578, value, 0.001);
158	/// let value = Math::acos_deg(2.0);
159	/// assert!(value.is_nan());
160	/// let value = Math::acos_deg(-1.001);
161	/// assert!(value.is_nan());
162	/// ```
163	pub fn acos_deg(value: f32) -> f32 { Math::RAD_TO_DEG * Math::acos(value) }
164	
165	/// Computes the arc hyperbolic cosine (a.k.a. inverse hyperbolic cosine)
166	/// - **value**: The value to compute with
167	/// 
168	/// **Returns**: Returns the computed inverse hyperbolic cosine
169	/// #### Examples
170	/// ```
171	/// # use mathx::{Math,assert_range};
172	/// let value = Math::acosh(0.0);
173	/// assert!(value.is_nan());
174	/// let value = Math::acosh(1.0);
175	/// assert_range!(0.0, value);
176	/// let value = Math::acosh(1.54308063482);
177	/// assert_range!(1.0, value);
178	/// let value = Math::acosh(11.591954);
179	/// assert_range!(Math::PI, value);
180	/// let value = Math::acosh(7.6101246);
181	/// assert_range!(Math::E, value);
182	/// ```
183	pub fn acosh(value: f32) -> f32 {
184		#[cfg(not(feature = "no_std"))] { value.acosh() }
185		#[cfg(feature = "no_std")] {
186			if value < 1.0 { return f32::NAN; }
187			Math::ln(value + Math::sqrt(value * value - 1.0))
188		}
189	}
190	
191	/// Computes the arc sine (a.k.a. inverse sine) with the provided value
192	/// - **value**: The value to compute the arc sine with, must be within -1 and 1
193	/// 
194	/// **Returns**: Returns the angle at which the value exists in radians,
195	/// returns `NaN` if the value provided is less than -1 or greater than 1
196	/// #### Examples
197	/// ```
198	/// # use mathx::{Math,assert_range};
199	/// let value = Math::asin(0.0);
200	/// assert_range!(0.0, value);
201	/// let value = Math::asin(1.0);
202	/// assert_range!(Math::PI_OVER_2, value);
203	/// let value = Math::asin(-1.0);
204	/// assert_range!(-Math::PI_OVER_2, value);
205	/// let value = Math::asin(0.707106781);
206	/// assert_range!(Math::PI_OVER_4, value);
207	/// let value = Math::asin(-1.1);
208	/// assert!(value.is_nan());
209	/// let value = Math::asin(2.0);
210	/// assert!(value.is_nan());
211	/// let value = Math::asin(0.9999);
212	/// assert_range!(1.5566529, value);
213	/// let value = Math::asin(-0.25);
214	/// assert_range!(-0.25268024, value);
215	/// ```
216	pub fn asin(value: f32) -> f32 {
217		#[cfg(not(feature = "no_std"))] { value.asin() }
218		#[cfg(feature = "no_std")] {
219			if value < -1.0 || value > 1.0 { return f32::NAN; }
220			
221			let negate = if value < 0.0 { 1.0 } else { 0.0 };
222			let value = Math::abs(value);
223			let mut angle = -0.0187293;
224			
225			angle *= value;
226			angle += 0.0742610;
227			angle *= value;
228			angle -= 0.2121144;
229			angle *= value;
230			angle += Math::PI_OVER_2;
231			angle = Math::PI * 0.5 - Math::sqrt(1.0 - value) * angle;
232			
233			return angle - 2.0 * negate * angle;
234		}
235	}
236	
237	/// Computes the arc sine (a.k.a. inverse sine) with the provided value
238	/// - **value**: The value to compute the arc sine with, must be within -1 and 1
239	/// 
240	/// **Returns**: Returns the angle at which the value exists in degrees,
241	/// returns `NaN` if the value provided is less than -1 or greater than 1
242	/// #### Examples
243	/// ```
244	/// # use mathx::{Math,assert_range};
245	/// let value = Math::asin_deg(0.0);
246	/// assert_range!(0.0, value);
247	/// let value = Math::asin_deg(1.0);
248	/// assert_range!(90.0, value);
249	/// let value = Math::asin_deg(-1.0);
250	/// assert_range!(-90.0, value);
251	/// let value = Math::asin_deg(0.707106781);
252	/// assert_range!(45.0, value, 0.005);
253	/// let value = Math::asin_deg(-1.1);
254	/// assert!(value.is_nan());
255	/// let value = Math::asin_deg(2.0);
256	/// assert!(value.is_nan());
257	/// let value = Math::asin_deg(0.9999);
258	/// assert_range!(89.189644, value);
259	/// let value = Math::asin_deg(-0.25);
260	/// assert_range!(-14.477511, value, 0.005);
261	/// ```
262	pub fn asin_deg(value: f32) -> f32 { Math::RAD_TO_DEG * Math::asin(value) }
263	
264	/// Computes the arc hyperbolic sine (a.k.a. inverse hyperbolic sine)
265	/// - **value**: The value to compute with
266	/// 
267	/// **Returns**: Returns the computed inverse hyperbolic sine
268	/// #### Examples
269	/// ```
270	/// # use mathx::{Math,assert_range};
271	/// let value = Math::asinh(0.0);
272	/// assert_range!(0.0, value);
273	/// let value = Math::asinh(1.0);
274	/// assert_range!(0.8813736, value);
275	/// let value = Math::asinh(1.1752012);
276	/// assert_range!(1.0, value);
277	/// let value = Math::asinh(-1.1752012);
278	/// assert_range!(-1.0, value);
279	/// let value = Math::asinh(11.54874);
280	/// assert_range!(Math::PI, value);
281	/// let value = Math::asinh(7.5441365);
282	/// assert_range!(Math::E, value);
283	/// ```
284	pub fn asinh(value: f32) -> f32 {
285		#[cfg(not(feature = "no_std"))] { value.asinh() }
286		#[cfg(feature = "no_std")] {
287			Math::ln(value + Math::sqrt(value * value + 1.0))
288		}
289	}
290	
291	/// Computes the arc tangent (a.k.a. inverse tangent) with the provided value
292	/// - **value**: The value to compute the arc tangent with
293	/// 
294	/// **Returns**: Returns the angle at which the value exists in radians
295	/// #### Examples
296	/// ```
297	/// # use mathx::{Math,assert_range};
298	/// let value = Math::atan(0.0);
299	/// assert_range!(0.0, value);
300	/// let value = Math::atan(1.0);
301	/// assert_range!(Math::PI_OVER_4, value);
302	/// let value = Math::atan(-1.0);
303	/// assert_range!(-Math::PI_OVER_4, value);
304	/// let value = Math::atan(0.707106781);
305	/// assert_range!(0.615479708546, value);
306	/// let value = Math::atan(1.557407725);
307	/// assert_range!(1.0, value);
308	/// ```
309	pub fn atan(value: f32) -> f32 {
310		#[cfg(not(feature = "no_std"))] { value.atan() }
311		#[cfg(feature = "no_std")] {
312			Math::atan2(value, 1.0)
313		}
314	}
315	
316	/// Computes the arc tangent (a.k.a. inverse tangent) with the provided value
317	/// - **value**: The value to compute the arc tangent with
318	/// 
319	/// **Returns**: Returns the angle at which the value exists in degrees
320	/// #### Examples
321	/// ```
322	/// # use mathx::{Math,assert_range};
323	/// let value = Math::atan_deg(0.0);
324	/// assert_range!(0.0, value);
325	/// let value = Math::atan_deg(1.0);
326	/// assert_range!(45.0, value, 0.001);
327	/// let value = Math::atan_deg(-1.0);
328	/// assert_range!(-45.0, value, 0.001);
329	/// let value = Math::atan_deg(0.707106781);
330	/// assert_range!(35.26439, value, 0.001);
331	/// let value = Math::atan_deg(1.557407725);
332	/// assert_range!(57.29578, value);
333	/// ```
334	pub fn atan_deg(value: f32) -> f32 { Math::RAD_TO_DEG * Math::atan(value) }
335	
336	/// Computes the arc hyperbolic tangent (a.k.a. inverse hyperbolic tangent)
337	/// - **value**: The value to compute with
338	/// 
339	/// **Returns**: Returns the computed inverse hyperbolic tangent
340	/// #### Examples
341	/// ```
342	/// # use mathx::{Math,assert_range};
343	/// let value = Math::atanh(0.0);
344	/// assert_range!(0.0, value);
345	/// let value = Math::atanh(1.0);
346	/// assert!(value.is_infinite());
347	/// let value = Math::atanh(0.7615942);
348	/// assert_range!(1.0, value, 0.001);
349	/// let value = Math::atanh(-0.7615942);
350	/// assert_range!(-1.0, value, 0.001);
351	/// let value = Math::atanh(0.9962721);
352	/// assert_range!(Math::PI, value);
353	/// let value = Math::atanh(0.9913289);
354	/// assert_range!(Math::E, value);
355	/// ```
356	pub fn atanh(value: f32) -> f32 {
357		#[cfg(not(feature = "no_std"))] { value.atanh() }
358		#[cfg(feature = "no_std")] {
359			if value >= 1.0 { return f32::INFINITY; }
360			if value <= -1.0 { return f32::NEG_INFINITY; }
361			0.5 * Math::ln((1.0 + value) * (1.0 - value).recip())
362		}
363	}
364	
365	/// Computes the arc tangent (a.k.a. inverse tangent) with the provided x and y values
366	/// - **y**: The y value to compute the arc tangent with
367	/// - **x**: The x value to compute the arc tangent with
368	/// 
369	/// **Returns**: Returns the angle at with the two values divided exists in radians
370	/// #### Examples
371	/// ```
372	/// # use mathx::{Math,assert_range};
373	/// let value = Math::atan2(0.0, 1.0);
374	/// assert_range!(0.0, value);
375	/// let value = Math::atan2(1.0, 1.0);
376	/// assert_range!(Math::PI_OVER_4, value);
377	/// let value = Math::atan2(-1.0, 1.0);
378	/// assert_range!(-Math::PI_OVER_4, value);
379	/// let value = Math::atan2(5.0, 1.0);
380	/// assert_range!(1.3734008, value);
381	/// let value = Math::atan2(1.0, 5.0);
382	/// assert_range!(0.19739556, value);
383	/// let value = Math::atan2(-5.0, 1.0);
384	/// assert_range!(-1.3734008, value);
385	/// let value = Math::atan2(-1.0, 5.0);
386	/// assert_range!(-0.19739556, value);
387	/// ```
388	pub fn atan2(y: f32, x: f32) -> f32 {
389		#[cfg(not(feature = "no_std"))] { y.atan2(x) }
390		#[cfg(feature = "no_std")] {
391			let mut a = Math::abs(x);
392			let mut b = Math::abs(y);
393			let mut c = Math::max(a, b);
394			b = Math::min(a, b);
395			a = c.recip();
396			a = b * a;
397		  
398			let d = a * a;
399			c = -0.013480470;
400			c = c * d + 0.057477314;
401			c = c * d - 0.121239071;
402			c = c * d + 0.195635925;
403			c = c * d - 0.332994597;
404			c = c * d + 0.999995630;
405			a *= c;
406			
407			if Math::abs(y) > Math::abs(x) { a = Math::PI_OVER_2 - a; }
408			if x < 0.0 { a = Math::PI - a; }
409			if y < 0.0 { a *= -1.0; }
410			
411			return a;
412		}
413	}
414	
415	/// Computes the arc tangent (a.k.a. inverse tangent) with the provided x and y values
416	/// - **y**: The y value to compute the arc tangent with
417	/// - **x**: The x value to compute the arc tangent with
418	/// 
419	/// **Returns**: Returns the angle at with the two values divided exists in degrees
420	/// #### Examples
421	/// ```
422	/// # use mathx::{Math,assert_range};
423	/// let value = Math::atan2_deg(0.0, 1.0);
424	/// assert_range!(0.0, value);
425	/// let value = Math::atan2_deg(1.0, 1.0);
426	/// assert_range!(45.0, value, 0.005);
427	/// let value = Math::atan2_deg(-1.0, 1.0);
428	/// assert_range!(-45.0, value, 0.005);
429	/// let value = Math::atan2_deg(5.0, 1.0);
430	/// assert_range!(78.69007, value);
431	/// let value = Math::atan2_deg(1.0, 5.0);
432	/// assert_range!(11.309933, value);
433	/// let value = Math::atan2_deg(-5.0, 1.0);
434	/// assert_range!(-78.69007, value);
435	/// let value = Math::atan2_deg(-1.0, 5.0);
436	/// assert_range!(-11.309933, value);
437	/// ```
438	pub fn atan2_deg(y: f32, x: f32) -> f32 { Math::RAD_TO_DEG * Math::atan2(y, x) }
439	
440	/// Gets the smallest integer number that is greater than or equal to the given number
441	/// - **value**: The value to get the ceiling with
442	/// 
443	/// **Returns**: Returns the ceiling number
444	/// #### Examples
445	/// ```
446	/// # use mathx::Math;
447	/// let value = Math::ceil(-3.0);
448	/// assert_eq!(-3.0, value);
449	/// let value = Math::ceil(1.4);
450	/// assert_eq!(2.0, value);
451	/// let value = Math::ceil(2.9);
452	/// assert_eq!(3.0, value);
453	/// let value = Math::ceil(-4.9);
454	/// assert_eq!(-4.0, value);
455	/// let value = Math::ceil(-5.3);
456	/// assert_eq!(-5.0, value);
457	/// ```
458	pub fn ceil(value: f32) -> f32 {
459		#[cfg(not(feature = "no_std"))] { value.ceil() }
460		#[cfg(feature = "no_std")] {
461			let truncated = Math::trunc(value);
462			
463			if truncated == value { return truncated; }
464			
465			return truncated + if value < 0.0 { 0.0 } else { 1.0 };
466		}
467	}
468	
469	/// Clamps the value between the min and max values
470	/// - **value**: The value to clamp with
471	/// - **min**: The lower-bound minimum value to clamp to
472	/// - **max**: The upper-bound maximum value to clamp to
473	/// 
474	/// **Returns**: Returns the clamped value
475	/// #### Examples
476	/// ```
477	/// # use mathx::Math;
478	/// let value = Math::clamp(20.0, 0.0, 10.0);
479	/// assert_eq!(10.0, value);
480	/// let value = Math::clamp(20.0, 0.0, 100.0);
481	/// assert_eq!(20.0, value);
482	/// let value = Math::clamp(-0.001, 0.0, 10.0);
483	/// assert_eq!(0.0, value);
484	/// let value = Math::clamp(0.18, -0.1, 0.1);
485	/// assert_eq!(0.1, value);
486	/// ```
487	pub fn clamp(value: f32, min: f32, max: f32) -> f32 { value.clamp(min, max) }
488	
489	/// Computes the cosine of the given angle in radians
490	/// - **angle**: The angle to compute cosine with in radians
491	/// 
492	/// **Returns**: Returns a value from the computed cosine
493	/// #### Remarks
494	/// If you need to compute both `cos` and `sin` of the same angle, use `sin_cos` instead as it's more
495	/// performant to produce both values than calling `cos` and `sin` separately
496	/// #### Examples
497	/// ```
498	/// # use mathx::{Math,assert_range};
499	/// let value = Math::cos(0.0);
500	/// assert_range!(1.0, value);
501	/// let value = Math::cos(Math::PI_OVER_2);
502	/// assert_range!(0.0, value);
503	/// let value = Math::cos(Math::PI);
504	/// assert_range!(-1.0, value);
505	/// let value = Math::cos(Math::PI + Math::PI_OVER_2);
506	/// assert_range!(0.0, value);
507	/// let value = Math::cos(Math::TWO_PI);
508	/// assert_range!(1.0, value);
509	/// let value = Math::cos(Math::PI_OVER_4);
510	/// assert_range!(0.707106781, value);
511	/// let value = Math::cos(1.0);
512	/// assert_range!(0.540302306, value);
513	/// let value = Math::cos(-100.0);
514	/// assert_range!(0.862318872, value);
515	/// ```
516	pub fn cos(angle: f32) -> f32 { Math::sin_cos(angle).1 }
517	
518	/// Computes the cosine of the given angle in degrees
519	/// - **angle**: The angle to compute cosine with in degrees
520	/// 
521	/// **Returns**: Returns a value from the computed cosine
522	/// #### Remarks
523	/// If you need to compute both `cos_deg` and `sin_deg` of the same angle, use `sin_cos_deg` instead as it's more
524	/// performant to produce both values than calling `cos_deg` and `sin_deg` separately
525	/// #### Examples
526	/// ```
527	/// # use mathx::{Math,assert_range};
528	/// let value = Math::cos_deg(0.0);
529	/// assert_range!(1.0, value);
530	/// let value = Math::cos_deg(90.0);
531	/// assert_range!(0.0, value);
532	/// let value = Math::cos_deg(180.0);
533	/// assert_range!(-1.0, value);
534	/// let value = Math::cos_deg(270.0);
535	/// assert_range!(0.0, value);
536	/// let value = Math::cos_deg(360.0);
537	/// assert_range!(1.0, value);
538	/// let value = Math::cos_deg(45.0);
539	/// assert_range!(0.707106781, value);
540	/// let value = Math::cos_deg(57.29577951);
541	/// assert_range!(0.540302306, value);
542	/// let value = Math::cos_deg(-5729.577951);
543	/// assert_range!(0.862318872, value);
544	/// ```
545	pub fn cos_deg(angle: f32) -> f32 { Math::cos(Math::DEG_TO_RAD * angle) }
546	
547	/// Computes the hyperbolic cosine function
548	/// - **value**: The value to compute the hyperbolic cosine function
549	/// 
550	/// **Returns**: Returns the computed hyperbolic cosine function
551	/// #### Examples
552	/// ```
553	/// # use mathx::{Math,assert_range};
554	/// let value = Math::cosh(0.0);
555	/// assert_range!(1.0, value);
556	/// let value = Math::cosh(1.0);
557	/// assert_range!(1.54308063482, value);
558	/// let value = Math::cosh(-1.0);
559	/// assert_range!(1.54308063482, value);
560	/// let value = Math::cosh(Math::PI);
561	/// assert_range!(11.591954, value);
562	/// let value = Math::cosh(Math::E);
563	/// assert_range!(7.6101246, value);
564	/// ```
565	pub fn cosh(value: f32) -> f32 {
566		#[cfg(not(feature = "no_std"))] { value.cosh() }
567		#[cfg(feature = "no_std")] {
568			let exp = Math::exp(value);
569			
570			if exp.is_infinite() || exp.is_nan() {
571				if value > 0.0 { return f32::INFINITY; }
572				else { return f32::NEG_INFINITY; }
573			}
574			
575			(exp + exp.recip()) * 0.5
576		}
577	}
578	
579	/// Computes the cotangent of the given angle in radians
580	/// - **angle**: The angle to compute the cotangent with in radians
581	/// 
582	/// **Returns**: Returns the computed cotangent value
583	/// #### Examples
584	/// ```
585	/// # use mathx::{Math,assert_range};
586	/// let value = Math::cot(Math::PI_OVER_2);
587	/// assert_range!(0.0, value);
588	/// let value = Math::cot(Math::PI + Math::PI_OVER_2);
589	/// assert_range!(0.0, value);
590	/// let value = Math::cot(Math::PI_OVER_4);
591	/// assert_range!(1.0, value);
592	/// let value = Math::cot(1.0);
593	/// assert_range!(0.642092616, value);
594	/// let value = Math::cot(-100.0);
595	/// assert_range!(1.702956919, value);
596	/// ```
597	pub fn cot(angle: f32) -> f32 { Math::tan(angle).recip() }
598	
599	/// Computes the cotangent of the given angle in degrees
600	/// - **angle**: The angle to compute the cotangent with in degrees
601	/// 
602	/// **Returns**: Returns the computed cotangent value
603	/// #### Examples
604	/// ```
605	/// # use mathx::{Math,assert_range};
606	/// let value = Math::cot_deg(90.0);
607	/// assert_range!(0.0, value);
608	/// let value = Math::cot_deg(270.0);
609	/// assert_range!(0.0, value);
610	/// let value = Math::cot_deg(45.0);
611	/// assert_range!(1.0, value);
612	/// let value = Math::cot_deg(57.29577951);
613	/// assert_range!(0.642092616, value);
614	/// let value = Math::cot_deg(-5729.577951);
615	/// assert_range!(1.702956919, value);
616	/// ```
617	pub fn cot_deg(angle: f32) -> f32 { Math::cot(Math::DEG_TO_RAD * angle) }
618	
619	/// Computes the cosecant of the given angle in radians
620	/// - **angle**: The angle to compute the cosecant with in radians
621	/// 
622	/// **Returns**: Returns the computed cosecant value
623	/// #### Examples
624	/// ```
625	/// # use mathx::{Math,assert_range};
626	/// let value = Math::csc(Math::PI_OVER_2);
627	/// assert_range!(1.0, value);
628	/// let value = Math::csc(Math::PI + Math::PI_OVER_2);
629	/// assert_range!(-1.0, value);
630	/// let value = Math::csc(Math::PI_OVER_4);
631	/// assert_range!(1.414213562, value);
632	/// let value = Math::csc(1.0);
633	/// assert_range!(1.188395106, value);
634	/// let value = Math::csc(-100.0);
635	/// assert_range!(1.974857531, value);
636	/// ```
637	pub fn csc(angle: f32) -> f32 { Math::sin(angle).recip() }
638	
639	/// Computes the cosecant of the given angle in degrees
640	/// - **angle**: The angle to compute the cosecant with in degrees
641	/// 
642	/// **Returns**: Returns the computed cosecant value
643	/// #### Examples
644	/// ```
645	/// # use mathx::{Math,assert_range};
646	/// let value = Math::csc_deg(90.0);
647	/// assert_range!(1.0, value);
648	/// let value = Math::csc_deg(270.0);
649	/// assert_range!(-1.0, value);
650	/// let value = Math::csc_deg(45.0);
651	/// assert_range!(1.414213562, value);
652	/// let value = Math::csc_deg(57.29577951);
653	/// assert_range!(1.188395106, value);
654	/// let value = Math::csc_deg(-5729.577951);
655	/// assert_range!(1.974857531, value);
656	/// ```
657	pub fn csc_deg(angle: f32) -> f32 { Math::csc(Math::DEG_TO_RAD * angle) }
658	
659	/// Converts the value from degrees to radians
660	/// - **degrees**: The value in degrees to convert
661	/// 
662	/// **Returns**: Returns the value in radians
663	/// #### Examples
664	/// ```
665	/// # use mathx::Math;
666	/// let value = Math::deg2rad(35.0);
667	/// assert_eq!(0.610865238198, value);
668	/// let value = Math::deg2rad(300.0);
669	/// assert_eq!(5.23598775598, value);
670	/// ```
671	pub fn deg2rad(degrees: f32) -> f32 { Math::DEG_TO_RAD * degrees }
672	
673	/// Computes e^x
674	/// - **value**: The value to compute with
675	/// 
676	/// **Returns**: Returns the computed e^x
677	/// #### Examples
678	/// ```
679	/// # use mathx::{Math,assert_range};
680	/// let value = Math::exp(0.0);
681	/// assert_range!(1.0, value);
682	/// let value = Math::exp(-10.0);
683	/// assert_range!(0.000004539993, value);
684	/// let value = Math::exp(10.0);
685	/// assert_range!(22026.465, value);
686	/// let value = Math::exp(12.34);
687	/// assert_range!(228661.98, value, 0.05);
688	/// let value = Math::exp(2.9);
689	/// assert_range!(18.174147, value);
690	/// ```
691	pub fn exp(value: f32) -> f32 {
692		#[cfg(not(feature = "no_std"))] { value.exp() }
693		#[cfg(feature = "no_std")] {
694			if value < 0.0 { return Math::exp(-value).recip(); }
695			
696			let mut result = 1.0;
697			let mut term = 1.0;
698			let mut n = 1;
699			
700			while n <= 100 {
701				term *= value / n as f32;
702				result += term;
703				n += 1;
704			}
705			
706			return result;
707		}
708	}
709	
710	/// Computes 2^x
711	/// - **value**: The value to compute with
712	/// 
713	/// **Returns**: Returns the computed 2^x
714	/// #### Examples
715	/// ```
716	/// # use mathx::{Math,assert_range};
717	/// let value = Math::exp2(0.0);
718	/// assert_range!(1.0, value);
719	/// let value = Math::exp2(-10.0);
720	/// assert_range!(0.0009765625, value);
721	/// let value = Math::exp2(10.0);
722	/// assert_range!(1024.0, value, 0.0002);
723	/// let value = Math::exp2(12.34);
724	/// assert_range!(5184.5396, value, 0.05);
725	/// let value = Math::exp2(2.9);
726	/// assert_range!(7.464265, value);
727	/// ```
728	pub fn exp2(value: f32) -> f32 {
729		#[cfg(not(feature = "no_std"))] { value.exp2() }
730		#[cfg(feature = "no_std")] {
731			Math::exp(value * Math::LN2)
732		}
733	}
734	
735	/// Gets the largest integer number that is less than or equal to the given number
736	/// - **value**: The value to get the floor with
737	/// 
738	/// **Returns**: Returns the floored number
739	/// #### Examples
740	/// ```
741	/// # use mathx::Math;
742	/// let value = Math::floor(-3.0);
743	/// assert_eq!(-3.0, value);
744	/// let value = Math::floor(1.4);
745	/// assert_eq!(1.0, value);
746	/// let value = Math::floor(2.9);
747	/// assert_eq!(2.0, value);
748	/// let value = Math::floor(-4.9);
749	/// assert_eq!(-5.0, value);
750	/// let value = Math::floor(-5.3);
751	/// assert_eq!(-6.0, value);
752	/// ```
753	pub fn floor(value: f32) -> f32 {
754		#[cfg(not(feature = "no_std"))] { value.floor() }
755		#[cfg(feature = "no_std")] {
756			let truncated = Math::trunc(value);
757			
758			if truncated == value { return truncated; }
759			
760			return truncated - if value < 0.0 { 1.0 } else { 0.0 };
761		}
762	}
763	
764	/// Gets the fractional part of the value, getting only a value between 0 and 1
765	/// - **value**: The value to get the fraction from
766	/// 
767	/// **Returns**: Returns the fraction of the given number
768	/// #### Examples
769	/// ```
770	/// # use mathx::{Math,assert_range};
771	/// let value = Math::fract(3.0);
772	/// assert_range!(0.0, value);
773	/// let value = Math::fract(-3.0);
774	/// assert_range!(0.0, value);
775	/// let value = Math::fract(4.9);
776	/// assert_range!(0.9, value);
777	/// let value = Math::fract(-4.9);
778	/// assert_range!(0.1, value);
779	/// let value = Math::fract(12.34);
780	/// assert_range!(0.34, value);
781	/// ```
782	pub fn fract(value: f32) -> f32 { value - Math::floor(value) }
783	
784	/// Linearly interpolates between the first and second values
785	/// - **a**: The first value to start from
786	/// - **b**: The second value to end from
787	/// - **t**: The ratio value to interpolate between both values. Clamped between 0.0 and 1.0
788	/// 
789	/// **Returns**: Returns the interpolated value
790	/// #### Examples
791	/// ```
792	/// # use mathx::Math;
793	/// let value = Math::lerp(0.0, 1.0, 0.5);
794	/// assert_eq!(0.5, value);
795	/// let value = Math::lerp(0.0, 0.1, 0.9);
796	/// assert_eq!(0.089999996, value);
797	/// let value = Math::lerp(-10.0, 10.0, 0.6);
798	/// assert_eq!(2.0, value);
799	/// let value = Math::lerp(-10.0, -4.0, 0.7);
800	/// assert_eq!(-5.8, value);
801	/// ```
802	pub fn lerp(a: f32, b: f32, t: f32) -> f32 { Math::lerp_unclamped(a, b, Math::clamp(t, 0.0, 1.0)) }
803	
804	/// Linearly interpolates between the first and second values (not clamped)
805	/// - **a**: The first value to start from
806	/// - **b**: The second value to end from
807	/// - **t**: The ratio value to interpolate between both values
808	/// 
809	/// **Returns**: Returns the interpolated value
810	/// #### Examples
811	/// ```
812	/// # use mathx::Math;
813	/// let value = Math::lerp_unclamped(0.0, 1.0, 0.5);
814	/// assert_eq!(0.5, value);
815	/// let value = Math::lerp_unclamped(0.0, 0.1, 0.9);
816	/// assert_eq!(0.089999996, value);
817	/// let value = Math::lerp_unclamped(-10.0, 10.0, 0.6);
818	/// assert_eq!(2.0, value);
819	/// let value = Math::lerp_unclamped(-10.0, -4.0, 0.7);
820	/// assert_eq!(-5.8, value);
821	/// ```
822	pub fn lerp_unclamped(a: f32, b: f32, t: f32) -> f32 { a + t * (b - a) }
823	
824	/// Computes the natural log of the given number
825	/// - **value**: The value to compute the natural log of
826	/// 
827	/// **Returns**: Returns the natural log of the given value. Returns `infinity` if the value infinity
828	/// and `-infinity` if the value is 0.0. Returns `NaN` if the value is `NaN` or less than 0.0
829	/// #### Examples
830	/// ```
831	/// # use mathx::{Math,assert_range};
832	/// let value = Math::ln(1.0);
833	/// assert_range!(0.0, value);
834	/// let value = Math::ln(100.0);
835	/// assert_range!(4.60517018599, value);
836	/// let value = Math::ln(0.01);
837	/// assert_range!(-4.60517018599, value);
838	/// let value = Math::ln(Math::E);
839	/// assert_range!(1.0, value);
840	/// let value = Math::ln(2.0);
841	/// assert_range!(0.69314718056, value);
842	/// let value = Math::ln(10.0);
843	/// assert_range!(2.30258509299, value);
844	/// let value = Math::ln(-10.0);
845	/// assert!(value.is_nan());
846	/// let value = Math::ln(0.0);
847	/// assert!(value.is_infinite());
848	/// ```
849	pub fn ln(value: f32) -> f32 {
850		#[cfg(not(feature = "no_std"))] { value.ln() }
851		#[cfg(feature = "no_std")] {
852			if value.is_nan() { return f32::NAN; }
853			if value == 0.0 { return f32::NEG_INFINITY; }
854			if value < 0.0 { return f32::NAN; }
855			if value < 1.0 { return -Math::ln(value.recip()); }
856			if value.is_infinite() { return f32::INFINITY; }
857			if value == 1.0 { return 0.0; }
858			
859			let mut x = value;
860			let mut ln10_count = 0;
861			let mut ln2_count = 0;
862			
863			while x > 10.0 {
864				x /= 10.0;
865				ln10_count += 1;
866			}
867			while x >= 2.0 {
868				x /= 2.0;
869				ln2_count += 1;
870			}
871			
872			if x == 1.0 { return ln2_count as f32 * Math::LN2 + ln10_count as f32 * Math::LN10; }
873			
874			let term = x - 1.0;
875			let mut power = term;
876			let mut series = power;
877			
878			for i in 2..17 {
879				let negative = if i % 2 == 0 { -1.0 } else { 1.0 };
880				
881				power *= term;
882				series += negative * power / i as f32;
883			}
884			
885			return ln2_count as f32 * Math::LN2 + ln10_count as f32 * Math::LN10 + series;
886		}
887	}
888	
889	/// Computes the natural log of the given number plus one
890	/// - **value**: The value to compute the natural log of
891	/// 
892	/// **Returns**: Returns the natural log of the given value. Returns `infinity` if the value infinity
893	/// and `-infinity` if the value is -1.0. Returns `NaN` if the value is `NaN` or less than -1.0
894	/// #### Examples
895	/// ```
896	/// # use mathx::{Math,assert_range};
897	/// let value = Math::ln_1p(1.0);
898	/// assert_range!(0.6931472, value);
899	/// let value = Math::ln_1p(100.0);
900	/// assert_range!(4.6151204, value);
901	/// let value = Math::ln_1p(0.01);
902	/// assert_range!(0.0099503305, value);
903	/// let value = Math::ln_1p(2.0);
904	/// assert_range!(1.0986123, value);
905	/// let value = Math::ln_1p(10.0);
906	/// assert_range!(2.3978953, value);
907	/// let value = Math::ln_1p(-10.0);
908	/// assert!(value.is_nan());
909	/// let value = Math::ln_1p(0.0);
910	/// assert_range!(0.0, value);
911	/// ```
912	pub fn ln_1p(value: f32) -> f32 {
913		#[cfg(not(feature = "no_std"))] { value.ln_1p() }
914		#[cfg(feature = "no_std")] { Math::ln(value + 1.0) }
915	}
916	
917	/// Computes the log of the given number with a given base
918	/// - **value**: The value to compute the logarithm with
919	/// - **base**: The base of the logarithm
920	/// 
921	/// **Returns**: Returns the computed logarithm
922	/// #### Examples
923	/// ```
924	/// # use mathx::{Math,assert_range};
925	/// let value = Math::log(2.0, 2.0);
926	/// assert_range!(1.0, value);
927	/// let value = Math::log(1.0, 2.0);
928	/// assert_range!(0.0, value);
929	/// let value = Math::log(10.0, 2.0);
930	/// assert_range!(3.32192809489, value);
931	/// let value = Math::log(16.0, 4.0);
932	/// assert_range!(2.0, value);
933	/// let value = Math::log(2.0, 1.0);
934	/// assert!(value.is_infinite());
935	/// ```
936	pub fn log(value: f32, base: f32) -> f32 {
937		#[cfg(not(feature = "no_std"))] { value.log(base) }
938		#[cfg(feature = "no_std")] { Math::ln(value) * Math::ln(base).recip() }
939	}
940	
941	/// Computes the log of the given number with base 10
942	/// - **value**: The value to compute the log with
943	/// 
944	/// **Returns**: Returns the computed log in base 10
945	/// #### Examples
946	/// ```
947	/// # use mathx::{Math,assert_range};
948	/// let value = Math::log10(1.0);
949	/// assert_range!(0.0, value);
950	/// let value = Math::log10(2.0);
951	/// assert_range!(0.301029995664, value);
952	/// let value = Math::log10(10.0);
953	/// assert_range!(1.0, value);
954	/// let value = Math::log10(50.0);
955	/// assert_range!(1.69897000434, value);
956	/// let value = Math::log10(100.0);
957	/// assert_range!(2.0, value);
958	/// ```
959	pub fn log10(value: f32) -> f32 {
960		#[cfg(not(feature = "no_std"))] { value.log10() }
961		#[cfg(feature = "no_std")] { Math::ln(value) * Math::LN10.recip() }
962	}
963	
964	/// Computes the log of the given number with base 2
965	/// - **value**: The value to compute the log with
966	/// 
967	/// **Returns**: Returns the computed log in base 2
968	/// #### Examples
969	/// ```
970	/// # use mathx::{Math,assert_range};
971	/// let value = Math::log2(1.0);
972	/// assert_range!(0.0, value);
973	/// let value = Math::log2(2.0);
974	/// assert_range!(1.0, value);
975	/// let value = Math::log2(10.0);
976	/// assert_range!(3.32192809489, value);
977	/// let value = Math::log2(16.0);
978	/// assert_range!(4.0, value);
979	/// ```
980	pub fn log2(value: f32) -> f32 {
981		#[cfg(not(feature = "no_std"))] { value.log2() }
982		#[cfg(feature = "no_std")] { Math::ln(value) * Math::LN2.recip() }
983	}
984	
985	/// Maps the value from one range into another range
986	/// - **value**: The value to map
987	/// - **in_range**: The starting input range to map from
988	/// - **out_range**: The ending output range to map to
989	/// 
990	/// **Returns**: Returns the mapped value
991	/// #### Examples
992	/// ```
993	/// # use mathx::Math;
994	/// let value = Math::map(1.5, 1.0..2.0, 1.0..2.0);
995	/// assert_eq!(1.5, value);
996	/// let value = Math::map(1.0, 0.0..10.0, 0.0..1.0);
997	/// assert_eq!(0.1, value);
998	/// let value = Math::map(11.0, 0.0..10.0, 0.0..1.0);
999	/// assert_eq!(1.1, value);
1000	/// let value = Math::map(1.0, -10.0..10.0, 0.0..1.0);
1001	/// assert_eq!(0.55, value);
1002	/// let value = Math::map(-10.0, -100.0..-10.0, 10.0..100.0);
1003	/// assert_eq!(100.0, value);
1004	/// ```
1005	pub fn map(value: f32, in_range: Range<f32>, out_range: Range<f32>) -> f32 {
1006		return
1007			(value - in_range.start)
1008			* (out_range.end - out_range.start)
1009			/ (in_range.end - in_range.start)
1010			+ out_range.start;
1011	}
1012	
1013	/// Gets the maximum value between the two values
1014	/// - **a**: The first value to get the maximum value from
1015	/// - **b**: The second value to get the maximum value from
1016	/// 
1017	/// **Returns**: Returns the maximum number between the two values
1018	/// #### Examples
1019	/// ```
1020	/// # use mathx::Math;
1021	/// let value = Math::max(-1.0, 1.0);
1022	/// assert_eq!(1.0, value);
1023	/// let value = Math::max(-19.0, -19.1);
1024	/// assert_eq!(-19.0, value);
1025	/// ```
1026	pub fn max(a: f32, b: f32) -> f32 { a.max(b) }
1027	
1028	/// Gets the minimum value between the two values
1029	/// - **a**: The first value to get the minimum value from
1030	/// - **b**: The second value to get the minimum value from
1031	/// 
1032	/// **Returns**: Returns the minimum number between the two values
1033	/// #### Examples
1034	/// ```
1035	/// # use mathx::Math;
1036	/// let value = Math::min(-1.0, 1.0);
1037	/// assert_eq!(-1.0, value);
1038	/// let value = Math::min(-19.0, -19.1);
1039	/// assert_eq!(-19.1, value);
1040	/// ```
1041	pub fn min(a: f32, b: f32) -> f32 { a.min(b) }
1042	
1043	/// Gets the minimum and maximum value returned as a tuple correctly sorted
1044	/// - **a**: The first value to get the minimum and maximum value from
1045	/// - **b**: The second value to get the minimum and maximum value from
1046	/// 
1047	/// **Returns**: Returns a tuple that holds the minimum and maximum values respectively
1048	/// #### Examples
1049	/// ```
1050	/// # use mathx::Math;
1051	/// let value = Math::min_max(-1.0, 1.0);
1052	/// assert_eq!((-1.0, 1.0), value);
1053	/// let value = Math::min_max(-19.0, -19.1);
1054	/// assert_eq!((-19.1, -19.0), value);
1055	/// ```
1056	pub fn min_max(a: f32, b: f32) -> (f32, f32) { (Math::min(a, b), Math::max(a, b)) }
1057	
1058	/// Raised the value by the power (as a floating point number)
1059	/// - **value**: The value to raise with
1060	/// - **power**: The power to raise by
1061	/// 
1062	/// **Returns**: Returns the value raised by the power
1063	/// #### Examples
1064	/// ```
1065	/// # use mathx::{Math,assert_range};
1066	/// let value = Math::pow(1.0, 0.0);
1067	/// assert_range!(1.0, value);
1068	/// let value = Math::pow(1.0, 10.0);
1069	/// assert_range!(1.0, value);
1070	/// let value = Math::pow(2.0, 10.0);
1071	/// assert_range!(1024.0, value, 0.0002);
1072	/// let value = Math::pow(40.0, 1.2);
1073	/// assert_range!(83.65118, value);
1074	/// let value = Math::pow(3.0, -2.3);
1075	/// assert_range!(0.07991368, value);
1076	/// ```
1077	pub fn pow(value: f32, power: f32) -> f32 {
1078		if power == 0.0 { return 1.0; }
1079		if power == 1.0 { return value; }
1080		if value == 1.0 { return 1.0; }
1081		if value == 2.0 { return Math::exp2(power); }
1082		
1083		let fract = Math::fract(power);
1084		
1085		if fract == 0.0 { return Math::pow_i32(value, Math::floor(power) as i32); }
1086		
1087		#[cfg(not(feature = "no_std"))] { value.powf(power) }
1088		#[cfg(feature = "no_std")] {
1089			Math::exp(power * Math::ln(value))
1090		}
1091	}
1092	
1093	/// Gets the power of the given number by the other given number, with the power being an `i32`
1094	/// - **a**: The base number to power
1095	/// - **b**: The number to power with
1096	/// 
1097	/// **Returns**: Returns the powered number
1098	/// #### Examples
1099	/// ```
1100	/// # use mathx::{Math,assert_range};
1101	/// let value = Math::pow_i32(3.0, 5);
1102	/// assert_range!(243.0, value);
1103	/// let value = Math::pow_i32(10.45, 3);
1104	/// assert_range!(1141.166, value, 0.001);
1105	/// let value = Math::pow_i32(0.0, 0);
1106	/// assert_range!(1.0, value);
1107	/// let value = Math::pow_i32(10.0, 0);
1108	/// assert_range!(1.0, value);
1109	/// let value = Math::pow_i32(0.0, 2);
1110	/// assert_range!(0.0, value);
1111	/// let value = Math::pow_i32(2.0, -3);
1112	/// assert_range!(0.125, value);
1113	/// ```
1114	pub fn pow_i32(a: f32, b: i32) -> f32 {
1115		#[cfg(not(feature = "no_std"))] { a.powi(b) }
1116		#[cfg(feature = "no_std")] {
1117			if b == 0 { return 1.0 }
1118			
1119			let mut result = a;
1120			
1121			for _ in 1..Math::abs_i32(b) {
1122				result *= a;
1123			}
1124			
1125			if b < 0 { result.recip() }
1126			else { result }
1127		}
1128	}
1129	
1130	/// Converts the value from radians to degrees
1131	/// - **radians**: The value in radians to convert
1132	/// 
1133	/// **Returns**: Returns the value in degrees
1134	/// #### Examples
1135	/// ```
1136	/// # use mathx::Math;
1137	/// let value = Math::rad2deg(1.0);
1138	/// assert_eq!(57.2957795131, value);
1139	/// let value = Math::rad2deg(4.0);
1140	/// assert_eq!(229.183118052, value);
1141	/// ```
1142	pub fn rad2deg(radians: f32) -> f32 { Math::RAD_TO_DEG * radians }
1143	
1144	/// Repeats the value around the range, making sure it stays within the range
1145	/// - **value**: The value to repeat
1146	/// - **range**: The range to repeat around
1147	/// 
1148	/// **Returns**: Returns the wrapped value
1149	/// #### Examples
1150	/// ```
1151	/// # use mathx::{Math,assert_range};
1152	/// let value = Math::repeat(1.0, 0.0..2.0);
1153	/// assert_range!(1.0, value);
1154	/// let value = Math::repeat(1.0, 2.0..3.0);
1155	/// assert_range!(3.0, value);
1156	/// let value = Math::repeat(5.3, 0.0..3.0);
1157	/// assert_range!(2.3, value);
1158	/// let value = Math::repeat(-4.0, 0.0..1.23);
1159	/// assert_range!(0.31, value);
1160	/// let value = Math::repeat(-4.0, 10.0..12.23);
1161	/// assert_range!(10.620003, value);
1162	/// ```
1163	pub fn repeat(value: f32, range: Range<f32>) -> f32 {
1164		if value >= range.start && value <= range.end {
1165			return value;
1166		}
1167		
1168		let x = value - range.start;
1169		let distance = range.end - range.start;
1170		
1171		if x < 0.0 {
1172			return range.end - distance * Math::fract(x * distance.recip());
1173		}
1174		
1175		return distance * Math::fract(x * distance.recip()) + range.start;
1176	}
1177	
1178	/// Rounds the given value to the nearest zero
1179	/// - **value**: The value to round with
1180	/// 
1181	/// **Returns**: Returns the rounded value
1182	/// #### Examples
1183	/// ```
1184	/// # use mathx::Math;
1185	/// let value = Math::round(0.0);
1186	/// assert_eq!(0.0, value);
1187	/// let value = Math::round(1.1);
1188	/// assert_eq!(1.0, value);
1189	/// let value = Math::round(2.9);
1190	/// assert_eq!(3.0, value);
1191	/// let value = Math::round(3.5);
1192	/// assert_eq!(4.0, value);
1193	/// let value = Math::round(-4.5);
1194	/// assert_eq!(-5.0, value);
1195	/// let value = Math::round(-5.45);
1196	/// assert_eq!(-5.0, value);
1197	/// ```
1198	pub fn round(value: f32) -> f32 {
1199		#[cfg(not(feature = "no_std"))] { value.round() }
1200		#[cfg(feature = "no_std")] {
1201			let mut fraction = Math::fract(value);
1202			let truncated = Math::trunc(value);
1203			
1204			if value < 0.0 && fraction > 0.0 { fraction = 1.0 - fraction; }
1205			
1206			if fraction >= 0.5 {
1207				return truncated + Math::sign(value);
1208			}
1209			
1210			return truncated;
1211		}
1212	}
1213	
1214	/// Rounds the value up to the given amount of digits past the decimal
1215	/// - **value**: The value to round with
1216	/// - **digits**: The digit past the decimal to round to, must be between -15 and 15
1217	/// 
1218	/// #### Examples
1219	/// ```
1220	/// # use mathx::Math;
1221	/// let value = Math::round_to_digit(1.0, 0);
1222	/// assert_eq!(1.0, value);
1223	/// let value = Math::round_to_digit(-1.0, 0);
1224	/// assert_eq!(-1.0, value);
1225	/// let value = Math::round_to_digit(1.525, 0);
1226	/// assert_eq!(2.0, value);
1227	/// let value = Math::round_to_digit(1.525, 1);
1228	/// assert_eq!(1.5, value);
1229	/// let value = Math::round_to_digit(1.525, 2);
1230	/// assert_eq!(1.53, value);
1231	/// let value = Math::round_to_digit(-1.525, 0);
1232	/// assert_eq!(-2.0, value);
1233	/// let value = Math::round_to_digit(-1.525, 2);
1234	/// assert_eq!(-1.53, value);
1235	/// let value = Math::round_to_digit(-2.4, 0);
1236	/// assert_eq!(-2.0, value);
1237	/// let value = Math::round_to_digit(-2.6, 0);
1238	/// assert_eq!(-3.0, value);
1239	/// ```
1240	pub fn round_to_digit(value: f32, digits: i32) -> f32 {
1241		let digits = digits.clamp(-15, 15);
1242		let pow10 = Math::pow_i32(10.0, digits);
1243		let powered = value * pow10;
1244		let mut fraction = Math::fract(powered);
1245		let truncated = Math::trunc(powered);
1246		
1247		if fraction == 0.0 { return value; }
1248		if value < 0.0 { fraction = 1.0 - fraction; }
1249		
1250		if fraction >= 0.5 {
1251			return (truncated + Math::sign(value)) / pow10;
1252		}
1253		
1254		return truncated / pow10;
1255	}
1256	
1257	/// Computes the secant of the given angle in radians
1258	/// - **angle**: The given angle to compute the secant with in radians
1259	/// 
1260	/// **Returns**: Returns the computed secant value
1261	/// #### Examples
1262	/// ```
1263	/// # use mathx::{Math,assert_range};
1264	/// let value = Math::sec(0.0);
1265	/// assert_range!(1.0, value);
1266	/// let value = Math::sec(Math::PI);
1267	/// assert_range!(-1.0, value);
1268	/// let value = Math::sec(Math::TWO_PI);
1269	/// assert_range!(1.0, value);
1270	/// let value = Math::sec(Math::PI_OVER_4);
1271	/// assert_range!(1.414213562, value);
1272	/// let value = Math::sec(1.0);
1273	/// assert_range!(1.850815718, value);
1274	/// let value = Math::sec(-100.0);
1275	/// assert_range!(1.159663823, value);
1276	/// ```
1277	pub fn sec(angle: f32) -> f32 { Math::cos(angle).recip() }
1278	
1279	/// Computes the secant of the given angle in degrees
1280	/// - **angle**: The given angle to compute the secant with in degrees
1281	/// 
1282	/// **Returns**: Returns the computed secant value
1283	/// #### Examples
1284	/// ```
1285	/// # use mathx::{Math,assert_range};
1286	/// let value = Math::sec_deg(0.0);
1287	/// assert_range!(1.0, value);
1288	/// let value = Math::sec_deg(180.0);
1289	/// assert_range!(-1.0, value);
1290	/// let value = Math::sec_deg(360.0);
1291	/// assert_range!(1.0, value);
1292	/// let value = Math::sec_deg(45.0);
1293	/// assert_range!(1.414213562, value);
1294	/// let value = Math::sec_deg(57.29577951);
1295	/// assert_range!(1.850815718, value);
1296	/// let value = Math::sec_deg(-5729.577951);
1297	/// assert_range!(1.159663823, value);
1298	/// ```
1299	pub fn sec_deg(angle: f32) -> f32 { Math::sec(Math::DEG_TO_RAD * angle) }
1300	
1301	/// Gets the sign (positive or negative) of the given value
1302	/// - **value**: The value to check the sign with
1303	/// 
1304	/// **Returns**: Returns 1.0 if the value is positive, and -1.0 if the value is negative
1305	/// #### Examples
1306	/// ```
1307	/// # use mathx::Math;
1308	/// let value = Math::sign(10.0);
1309	/// assert_eq!(1.0, value);
1310	/// let value = Math::sign(-10.0);
1311	/// assert_eq!(-1.0, value);
1312	/// let value = Math::sign(-0.0);
1313	/// assert_eq!(-1.0, value);
1314	/// ```
1315	pub fn sign(value: f32) -> f32 {
1316		#[cfg(not(feature = "no_std"))] { value.signum() }
1317		#[cfg(feature = "no_std")] {
1318			if value.is_nan() { return value; }
1319			if value <= -0.0 { -1.0 } else { 1.0 }
1320		}
1321	}
1322	
1323	/// Computes the sine of the given angle in radians
1324	/// - **angle**: The angle to compute sine with in radians
1325	/// 
1326	/// **Returns**: Returns a value from the computed sine
1327	/// #### Remarks
1328	/// If you need to compute both `cos` and `sin` of the same angle, use `sin_cos` instead as it's more
1329	/// performant to produce both values than calling `cos` and `sin` separately
1330	/// ##### Examples
1331	/// ```
1332	/// # use mathx::{Math,assert_range};
1333	/// let value = Math::sin(0.0);
1334	/// assert_range!(0.0, value);
1335	/// let value = Math::sin(Math::PI_OVER_2);
1336	/// assert_range!(1.0, value);
1337	/// let value = Math::sin(Math::PI);
1338	/// assert_range!(0.0, value);
1339	/// let value = Math::sin(Math::PI + Math::PI_OVER_2);
1340	/// assert_range!(-1.0, value);
1341	/// let value = Math::sin(Math::TWO_PI);
1342	/// assert_range!(0.0, value);
1343	/// let value = Math::sin(Math::PI_OVER_4);
1344	/// assert_range!(0.707106781, value);
1345	/// let value = Math::sin(1.0);
1346	/// assert_range!(0.841470985, value);
1347	/// let value = Math::sin(-100.0);
1348	/// assert_range!(0.506365641, value);
1349	/// ```
1350	pub fn sin(angle: f32) -> f32 { Math::sin_cos(angle).0 }
1351	
1352	/// Computes the sine of the given angle in degrees
1353	/// - **angle**: The angle to compute sine with in degrees
1354	/// 
1355	/// **Returns**: Returns a value from the computed sine
1356	/// #### Remarks
1357	/// If you need to compute both `cos_deg` and `sin_deg` of the same angle, use `sin_cos_deg` instead as it's more
1358	/// performant to produce both values than calling `cos_deg` and `sin_deg` separately
1359	/// ##### Examples
1360	/// ```
1361	/// # use mathx::{Math,assert_range};
1362	/// let value = Math::sin_deg(0.0);
1363	/// assert_range!(0.0, value);
1364	/// let value = Math::sin_deg(90.0);
1365	/// assert_range!(1.0, value);
1366	/// let value = Math::sin_deg(180.0);
1367	/// assert_range!(0.0, value);
1368	/// let value = Math::sin_deg(270.0);
1369	/// assert_range!(-1.0, value);
1370	/// let value = Math::sin_deg(360.0);
1371	/// assert_range!(0.0, value);
1372	/// let value = Math::sin_deg(45.0);
1373	/// assert_range!(0.707106781, value);
1374	/// let value = Math::sin_deg(57.29577951);
1375	/// assert_range!(0.841470985, value);
1376	/// let value = Math::sin_deg(-5729.577951);
1377	/// assert_range!(0.506365641, value);
1378	/// ```
1379	pub fn sin_deg(angle: f32) -> f32 { Math::sin(Math::DEG_TO_RAD * angle) }
1380	
1381	/// Computes the sine and cosine of the angle in radians
1382	/// - **angle**: The angle to compute the sine and cosine with in radians
1383	/// 
1384	/// **Returns**: Returns the sine and cosine (respectively) as a tuple
1385	/// #### Remarks
1386	/// If you need to compute both `cos` and `sin` of the same angle, this function is more
1387	/// performant to produce both values than calling `cos` and `sin` separately
1388	/// #### Examples
1389	/// ```
1390	/// # use mathx::{Math,assert_range_tuple2};
1391	/// let value = Math::sin_cos(0.0);
1392	/// assert_range_tuple2!((0.0, 1.0), value);
1393	/// let value = Math::sin_cos(Math::PI_OVER_2);
1394	/// assert_range_tuple2!((1.0, 0.0), value);
1395	/// let value = Math::sin_cos(Math::PI);
1396	/// assert_range_tuple2!((0.0, -1.0), value);
1397	/// let value = Math::sin_cos(Math::PI + Math::PI_OVER_2);
1398	/// assert_range_tuple2!((-1.0, 0.0), value);
1399	/// let value = Math::sin_cos(Math::TWO_PI);
1400	/// assert_range_tuple2!((0.0, 1.0), value);
1401	/// let value = Math::sin_cos(Math::PI_OVER_4);
1402	/// assert_range_tuple2!((0.707106781, 0.707106781), value);
1403	/// let value = Math::sin_cos(1.0);
1404	/// assert_range_tuple2!((0.841470985, 0.540302306), value);
1405	/// let value = Math::sin_cos(-100.0);
1406	/// assert_range_tuple2!((0.506365641, 0.862318872), value);
1407	/// ```
1408	pub fn sin_cos(angle: f32) -> (f32, f32) {
1409		#[cfg(not(feature = "no_std"))] { angle.sin_cos() }
1410		#[cfg(feature = "no_std")] {
1411			const ITERATIONS: i32 = 28;
1412			
1413			if angle < -Math::PI_OVER_2 || angle > Math::PI_OVER_2 {
1414				return if angle < 0.0 { Math::negate_tuple(Math::sin_cos(angle + Math::PI)) }
1415					else { Math::negate_tuple(Math::sin_cos(angle - Math::PI)) };
1416			}
1417			
1418			let mut cos = 0.60725293500888;
1419			let mut sin = 0.0_f32;
1420			let mut z = angle;
1421			
1422			for i in 0..ITERATIONS {
1423				let di = if z <= 0.0 { -1.0 } else { 1.0 };
1424				let new_cos = cos - (sin * di * Math::pow_i32(2.0, -i));
1425				let new_sin = sin + (cos * di * Math::pow_i32(2.0, -i));
1426				
1427				cos = new_cos;
1428				sin = new_sin;
1429				z -= di * Math::get_atan_for_cordic(i);
1430			}
1431			
1432			return (sin, cos);
1433		}
1434	}
1435	
1436	/// Computes the sine and cosine of the angle in degrees
1437	/// - **angle**: The angle to compute the sine and cosine with in degrees
1438	/// 
1439	/// **Returns**: Returns the sine and cosine (respectively) as a tuple
1440	/// #### Remarks
1441	/// If you need to compute both `cos_deg` and `sin_deg` of the same angle, this function is more
1442	/// performant to produce both values than calling `cos_deg` and `sin_deg` separately
1443	/// #### Examples
1444	/// ```
1445	/// # use mathx::{Math,assert_range_tuple2};
1446	/// let value = Math::sin_cos_deg(0.0);
1447	/// assert_range_tuple2!((0.0, 1.0), value);
1448	/// let value = Math::sin_cos_deg(90.0);
1449	/// assert_range_tuple2!((1.0, 0.0), value);
1450	/// let value = Math::sin_cos_deg(180.0);
1451	/// assert_range_tuple2!((0.0, -1.0), value);
1452	/// let value = Math::sin_cos_deg(270.0);
1453	/// assert_range_tuple2!((-1.0, 0.0), value);
1454	/// let value = Math::sin_cos_deg(360.0);
1455	/// assert_range_tuple2!((0.0, 1.0), value);
1456	/// let value = Math::sin_cos_deg(45.0);
1457	/// assert_range_tuple2!((0.707106781, 0.707106781), value);
1458	/// let value = Math::sin_cos_deg(57.29577951);
1459	/// assert_range_tuple2!((0.841470985, 0.540302306), value);
1460	/// let value = Math::sin_cos_deg(-5729.577951);
1461	/// assert_range_tuple2!((0.506365641, 0.862318872), value);
1462	/// ```
1463	pub fn sin_cos_deg(angle: f32) -> (f32, f32) { Math::sin_cos(Math::DEG_TO_RAD * angle) }
1464	
1465	/// Computes the hyperbolic sine function
1466	/// - **value**: The value to compute the hyperbolic sine function with
1467	/// 
1468	/// **Returns**: Returns the computed hyperbolic sine function
1469	/// #### Examples
1470	/// ```
1471	/// # use mathx::{Math,assert_range};
1472	/// let value = Math::sinh(0.0);
1473	/// assert_range!(0.0, value);
1474	/// let value = Math::sinh(1.0);
1475	/// assert_range!(1.1752012, value);
1476	/// let value = Math::sinh(-1.0);
1477	/// assert_range!(-1.1752012, value);
1478	/// let value = Math::sinh(Math::PI);
1479	/// assert_range!(11.54874, value);
1480	/// let value = Math::sinh(Math::E);
1481	/// assert_range!(7.5441365, value);
1482	/// ```
1483	pub fn sinh(value: f32) -> f32 {
1484		#[cfg(not(feature = "no_std"))] { value.sinh() }
1485		#[cfg(feature = "no_std")] {
1486			let exp = Math::exp(value);
1487			
1488			if exp.is_infinite() || exp.is_nan() {
1489				if value > 0.0 { return f32::INFINITY; }
1490				else { return f32::NEG_INFINITY; }
1491			}
1492			
1493			(exp - exp.recip()) * 0.5
1494		}
1495	}
1496	
1497	/// Computes a smooth Hermite interpolation that returns a number between 0.0 and 1.0
1498	/// - **value**: The value for the interpolation, where `left_edge` &lt; `value` &lt; `right_edge`
1499	/// - **left_edge**: The leftmost edge to where 0.0 would start at
1500	/// - **right_edge**: The rightmost edge where 1.0 would start at
1501	/// 
1502	/// **Returns**: Returns a smooth Hermite interpolation that returns a number between 0.0 and 1.0
1503	/// #### Examples
1504	/// ```
1505	/// # use mathx::Math;
1506	/// let value = Math::smoothstep(-1.0, 0.0, 1.5);
1507	/// assert_eq!(0.0, value);
1508	/// let value = Math::smoothstep(1.0, 0.0, 1.5);
1509	/// assert_eq!(0.7407408, value);
1510	/// let value = Math::smoothstep(2.0, 0.0, 1.5);
1511	/// assert_eq!(1.0, value);
1512	/// let value = Math::smoothstep(0.5, -1.0, 3.0);
1513	/// assert_eq!(0.31640625, value);
1514	/// ```
1515	pub fn smoothstep(value: f32, left_edge: f32, right_edge: f32) -> f32 {
1516		let y = Math::clamp((value - left_edge) / (right_edge - left_edge), 0.0, 1.0);
1517		
1518		return y * y * (3.0 - 2.0 * y);
1519	}
1520	
1521	/// Gets the square root of the given number
1522	/// - **value**: The number to square root
1523	/// 
1524	/// **Returns**: Returns the square root of the number, returns NaN if `value` is negative
1525	/// #### Examples
1526	/// ```
1527	/// # use mathx::{Math,assert_range};
1528	/// let value = Math::sqrt(16.0);
1529	/// assert_range!(4.0, value);
1530	/// let value = Math::sqrt(1023.835);
1531	/// assert_range!(31.9974217711, value);
1532	/// let value = Math::sqrt(-102.0);
1533	/// assert_eq!(true, f32::is_nan(value));
1534	/// let value = Math::sqrt(-0.0);
1535	/// assert_range!(0.0, value);
1536	/// let value = Math::sqrt(0.2146018);
1537	/// assert_range!(0.46325132, value);
1538	/// ```
1539	pub fn sqrt(value: f32) -> f32 {
1540		#[cfg(not(feature = "no_std"))] { value.sqrt() }
1541		#[cfg(feature = "no_std")] {
1542			if value < -0.0 { return f32::NAN; }
1543			if value == 0.0 { return 0.0; }
1544			if value == 1.0 { return 1.0; }
1545			
1546			let mut max = 50;
1547			let mut x = value;
1548			
1549			while max > 0 && Math::abs(x) > 0.000000001 {
1550				x = (x * x * x + 3.0 * value * x) / (3.0 * x * x + value);
1551				max -= 1;
1552			}
1553			
1554			return x;
1555		}
1556	}
1557	
1558	/// Gets the tangent  of the angle in radians
1559	/// - **angle**: The angle to compute the tangent with in radians
1560	/// 
1561	/// **Returns**: Returns the value from the computed tangent
1562	/// #### Examples
1563	/// ```
1564	/// # use mathx::{Math,assert_range};
1565	/// let value = Math::tan(0.0);
1566	/// assert_range!(0.0, value);
1567	/// let value = Math::tan(Math::PI);
1568	/// assert_range!(0.0, value);
1569	/// let value = Math::tan(Math::TWO_PI);
1570	/// assert_range!(0.0, value);
1571	/// let value = Math::tan(Math::PI_OVER_4);
1572	/// assert_range!(1.0, value);
1573	/// let value = Math::tan(1.0);
1574	/// assert_range!(1.557407725, value);
1575	/// let value = Math::tan(-100.0);
1576	/// assert_range!(0.587213915, value);
1577	/// ```
1578	pub fn tan(angle: f32) -> f32 {
1579		#[cfg(not(feature = "no_std"))] { angle.tan() }
1580		#[cfg(feature = "no_std")] {
1581			let (sin, cos) = Math::sin_cos(angle);
1582			
1583			sin / cos
1584		}
1585	}
1586	
1587	/// Gets the tangent  of the angle in degrees
1588	/// - **angle**: The angle to compute the tangent with in degrees
1589	/// 
1590	/// **Returns**: Returns the value from the computed tangent
1591	/// #### Examples
1592	/// ```
1593	/// # use mathx::{Math,assert_range};
1594	/// let value = Math::tan_deg(0.0);
1595	/// assert_range!(0.0, value);
1596	/// let value = Math::tan_deg(180.0);
1597	/// assert_range!(0.0, value);
1598	/// let value = Math::tan_deg(360.0);
1599	/// assert_range!(0.0, value);
1600	/// let value = Math::tan_deg(45.0);
1601	/// assert_range!(1.0, value);
1602	/// let value = Math::tan_deg(57.29577951);
1603	/// assert_range!(1.557407725, value);
1604	/// let value = Math::tan_deg(-5729.577951);
1605	/// assert_range!(0.587213915, value);
1606	/// ```
1607	pub fn tan_deg(angle: f32) -> f32 { Math::tan(Math::DEG_TO_RAD * angle) }
1608	
1609	
1610	/// Computes the hyperbolic tangent function
1611	/// - **value**: The value to compute the hyperbolic tangent function with
1612	/// 
1613	/// **Returns**: Returns the computed hyperbolic tangent function
1614	/// #### Examples
1615	/// ```
1616	/// # use mathx::{Math,assert_range};
1617	/// let value = Math::tanh(0.0);
1618	/// assert_range!(0.0, value);
1619	/// let value = Math::tanh(1.0);
1620	/// assert_range!(0.7615942, value);
1621	/// let value = Math::tanh(-1.0);
1622	/// assert_range!(-0.7615942, value);
1623	/// let value = Math::tanh(Math::PI);
1624	/// assert_range!(0.9962721, value);
1625	/// let value = Math::tanh(Math::E);
1626	/// assert_range!(0.9913289, value);
1627	/// ```
1628	pub fn tanh(value: f32) -> f32 {
1629		#[cfg(not(feature = "no_std"))] { value.tanh() }
1630		#[cfg(feature = "no_std")] {
1631			let exp = Math::exp(2.0 * value);
1632			
1633			if exp.is_infinite() || exp.is_nan() {
1634				if value > 0.0 { return 1.0; }
1635				else { return -1.0; }
1636			}
1637			
1638			(exp - 1.0) * (exp + 1.0).recip()
1639		}
1640	}
1641	
1642	/// Truncates the value of the floating point number
1643	/// - **value**: The number to truncate
1644	/// 
1645	/// **Returns**: Returns the truncated number
1646	/// #### Examples
1647	/// ```
1648	/// # use mathx::Math;
1649	/// let value = Math::trunc(123.456);
1650	/// assert_eq!(123.0, value);
1651	/// let value = Math::trunc(-5.4);
1652	/// assert_eq!(-5.0, value);
1653	/// let value = Math::trunc(6.0);
1654	/// assert_eq!(6.0, value);
1655	/// let value = Math::trunc(-0.0);
1656	/// assert_eq!(0.0, value);
1657	/// ```
1658	pub fn trunc(value: f32) -> f32 {
1659		#[cfg(not(feature = "no_std"))] { value.trunc() }
1660		#[cfg(feature = "no_std")] {
1661			(value as i32) as f32
1662		}
1663	}
1664}
1665
1666// Private Functions
1667impl Math {
1668	/// Gets the pre-calculated arc tangent values for use in the cordic algorithm
1669	/// - **index**: The index to get the pre-calculated value from
1670	/// 
1671	/// **Returns**: Returns the pre-calculated value for the arc tangent
1672	#[cfg(feature = "no_std")]
1673	pub(self) fn get_atan_for_cordic(index: i32) -> f32 {
1674		match index {
1675			0 => 0.7853982,
1676			1 => 0.4636476,
1677			2 => 0.24497867,
1678			3 => 0.124354996,
1679			4 => 0.06241881,
1680			5 => 0.031239834,
1681			6 => 0.015623729,
1682			7 => 0.007812341,
1683			8 => 0.0039062302,
1684			9 => 0.0019531226,
1685			10 => 0.0009765622,
1686			11 => 0.00048828122,
1687			12 => 0.00024414063,
1688			13 => 0.00012207031,
1689			14 => 0.000061035156,
1690			15 => 0.000030517578,
1691			16 => 0.00001525878906,
1692			17 => 0.00000762939453,
1693			18 => 0.00000381469727,
1694			19 => 0.00000190734863,
1695			20 => 0.00000095367432,
1696			21 => 0.00000047683716,
1697			22 => 0.00000023841858,
1698			23 => 0.00000011920929,
1699			24 => 0.00000005960464,
1700			25 => 0.00000002980232,
1701			26 => 0.00000001490116,
1702			27 => 0.00000000745058,
1703			_ => 0.0,
1704		}
1705	}
1706	
1707	/// Negates the tuple, multiplying both components by -1
1708	/// - **tuple**: The tuple to negate
1709	/// 
1710	/// **Returns**: Returns the negated tuple
1711	#[cfg(feature = "no_std")]
1712	pub(self) fn negate_tuple(tuple: (f32, f32)) -> (f32, f32) { (-tuple.0, -tuple.1) }
1713}
1714
1715#[doc(hidden)]
1716#[macro_export]
1717macro_rules! assert_range {
1718	($expected:expr, $value:expr) => {
1719		assert_range!($expected, $value, 0.0001);
1720	};
1721	($expected:expr, $value:expr, $epsilon:expr) => {
1722		if !Math::approx_epsilon($expected, $value, $epsilon) { panic!("\n\nleft: {:?}\nright: {:?}\n\n", $expected, $value); }
1723	};
1724}
1725
1726#[doc(hidden)]
1727#[macro_export]
1728macro_rules! assert_range_tuple2 {
1729	($expected:expr, $value:expr, $epsilon:expr) => {
1730		if !Math::approx_epsilon($expected.0, $value.0, $epsilon) || !Math::approx_epsilon($expected.1, $value.1,  $epsilon) { panic!("\n\nleft: {:?}\nright: {:?}\n\n", $expected, $value); }
1731	};
1732	($expected:expr, $value:expr) => {
1733		assert_range_tuple2!($expected, $value, 0.0001);
1734	};
1735}