malachite_base/num/conversion/from.rs
1// Copyright © 2025 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::num::arithmetic::traits::{ShrRoundAssign, UnsignedAbs};
10use crate::num::basic::floats::PrimitiveFloat;
11use crate::num::basic::integers::PrimitiveInt;
12use crate::num::basic::signeds::PrimitiveSigned;
13use crate::num::basic::unsigneds::PrimitiveUnsigned;
14use crate::num::conversion::mantissa_and_exponent::sci_mantissa_and_exponent_round;
15use crate::num::conversion::traits::{
16 ConvertibleFrom, OverflowingFrom, RoundingFrom, SaturatingFrom, SciMantissaAndExponent,
17 WrappingFrom,
18};
19use crate::num::float::NiceFloat;
20use crate::rounding_modes::RoundingMode::{self, *};
21use core::cmp::Ordering::{self, *};
22use core::ops::Neg;
23
24// This macro defines conversions from a type to itself.
25macro_rules! identity_conversion {
26 ($t:ty) => {
27 impl WrappingFrom<$t> for $t {
28 /// Converts a value to its own type. This conversion is always valid and always leaves
29 /// the value unchanged.
30 ///
31 /// # Worst-case complexity
32 /// Constant time and additional memory.
33 ///
34 /// # Examples
35 /// See [here](super::from#wrapping_from).
36 #[inline]
37 fn wrapping_from(value: $t) -> $t {
38 value
39 }
40 }
41
42 impl SaturatingFrom<$t> for $t {
43 /// Converts a value to its own type. This conversion is always valid and always leaves
44 /// the value unchanged.
45 ///
46 /// # Worst-case complexity
47 /// Constant time and additional memory.
48 ///
49 /// # Examples
50 /// See [here](super::from#saturating_from).
51 #[inline]
52 fn saturating_from(value: $t) -> $t {
53 value
54 }
55 }
56
57 impl OverflowingFrom<$t> for $t {
58 /// Converts a value to its own type. Since this conversion is always valid and always
59 /// leaves the value unchanged, the second component of the result is always false (no
60 /// overflow).
61 ///
62 /// # Worst-case complexity
63 /// Constant time and additional memory.
64 ///
65 /// # Examples
66 /// See [here](super::from#overflowing_from).
67 #[inline]
68 fn overflowing_from(value: $t) -> ($t, bool) {
69 (value, false)
70 }
71 }
72
73 impl ConvertibleFrom<$t> for $t {
74 /// Checks whether a value is convertible to its own type. The result is always `true`.
75 ///
76 /// # Worst-case complexity
77 /// Constant time and additional memory.
78 ///
79 /// # Examples
80 /// See [here](super::from#convertible_from).
81 #[inline]
82 fn convertible_from(_: $t) -> bool {
83 true
84 }
85 }
86 };
87}
88
89// This macro defines conversions from type $a to type $b, where every value of type $a is
90// representable by a value of type $b.
91macro_rules! lossless_conversion {
92 ($a:ty, $b:ident) => {
93 impl WrappingFrom<$a> for $b {
94 /// Converts a value to another type. This conversion is always valid and always leaves
95 /// the value unchanged.
96 ///
97 /// # Worst-case complexity
98 /// Constant time and additional memory.
99 ///
100 /// # Examples
101 /// See [here](super::from#wrapping_from).
102 #[inline]
103 fn wrapping_from(value: $a) -> $b {
104 $b::from(value)
105 }
106 }
107
108 impl SaturatingFrom<$a> for $b {
109 /// Converts a value to another type. This conversion is always valid and always leaves
110 /// the value unchanged.
111 ///
112 /// # Worst-case complexity
113 /// Constant time and additional memory.
114 ///
115 /// # Examples
116 /// See [here](super::from#saturating_from).
117 #[inline]
118 fn saturating_from(value: $a) -> $b {
119 $b::from(value)
120 }
121 }
122
123 impl OverflowingFrom<$a> for $b {
124 /// Converts a value to the value's type. Since this conversion is always valid and
125 /// always leaves the value unchanged, the second component of the result is always
126 /// false (no overflow).
127 ///
128 /// # Worst-case complexity
129 /// Constant time and additional memory.
130 ///
131 /// # Examples
132 /// See [here](super::from#overflowing_from).
133 #[inline]
134 fn overflowing_from(value: $a) -> ($b, bool) {
135 ($b::from(value), false)
136 }
137 }
138
139 impl ConvertibleFrom<$a> for $b {
140 /// Checks whether a value is convertible to a different type. The result is always
141 /// `true`.
142 ///
143 /// # Worst-case complexity
144 /// Constant time and additional memory.
145 ///
146 /// # Examples
147 /// See [here](super::from#convertible_from).
148 #[inline]
149 fn convertible_from(_: $a) -> bool {
150 true
151 }
152 }
153 };
154}
155
156fn saturating_from_lossy<A: TryFrom<B> + PrimitiveInt, B: PrimitiveInt + WrappingFrom<A>>(
157 value: A,
158) -> B {
159 if let Ok(b_max) = A::try_from(B::MAX) {
160 if value >= b_max {
161 return B::MAX;
162 }
163 }
164 if let Ok(b_min) = A::try_from(B::MIN) {
165 if value <= b_min {
166 return B::MIN;
167 }
168 }
169 B::wrapping_from(value)
170}
171
172fn overflowing_from_lossy<A: PrimitiveInt + WrappingFrom<B>, B: PrimitiveInt + WrappingFrom<A>>(
173 value: A,
174) -> (B, bool) {
175 let result = B::wrapping_from(value);
176 (
177 result,
178 (result >= B::ZERO) != (value >= A::ZERO) || A::wrapping_from(result) != value,
179 )
180}
181
182fn convertible_from_lossy<A: PrimitiveInt + WrappingFrom<B>, B: PrimitiveInt + WrappingFrom<A>>(
183 value: A,
184) -> bool {
185 let result = B::wrapping_from(value);
186 (result >= B::ZERO) == (value >= A::ZERO) && A::wrapping_from(result) == value
187}
188
189// This macro defines conversions from type $a to type $b, where not every value of type $a is
190// representable by a value of type $b.
191macro_rules! lossy_conversion {
192 ($a:ident, $b:ident) => {
193 #[allow(clippy::cast_lossless)]
194 impl WrappingFrom<$a> for $b {
195 /// Converts a value to another type. If the value cannot be represented in the new
196 /// type, it is wrapped.
197 ///
198 /// Let $W$ be the width of the target type.
199 ///
200 /// If the target type is unsigned, then $f_W(n) = m$, where $m < 2^W$ and $n + 2^W k =
201 /// m$ for some $k \in \Z$.
202 ///
203 /// If the target type is signed, then $f_W(n) = m$, where $-2^{W-1} \leq m < 2^{W-1}$
204 /// and $n + 2^W k = m$ for some $k \in \Z$.
205 ///
206 /// # Worst-case complexity
207 /// Constant time and additional memory.
208 ///
209 /// # Examples
210 /// See [here](super::from#wrapping_from).
211 #[inline]
212 fn wrapping_from(value: $a) -> $b {
213 value as $b
214 }
215 }
216
217 impl SaturatingFrom<$a> for $b {
218 /// Converts a value to another type. If the value cannot be represented in the new
219 /// type, the maximum or minimum value of the new type, whichever is closer, is
220 /// returned.
221 ///
222 /// Let $W$ be the width of the target type.
223 ///
224 /// If the target type is unsigned, then
225 /// $$
226 /// f_W(n) = \\begin{cases}
227 /// 0 & n < 0 \\\\
228 /// 2^W-1 & \text{if} \\quad n \geq 2^W, \\\\
229 /// n & \\text{otherwise}.
230 /// \\end{cases}
231 /// $$
232 ///
233 /// If the target type is signed, then
234 /// $$
235 /// f_W(n) = \\begin{cases}
236 /// -2^{W-1} & \text{if} \\quad n < -2^{W-1}, \\\\
237 /// 2^{W-1}-1 & \text{if} \\quad n \geq 2^{W-1}, \\\\
238 /// n & \\text{otherwise}.
239 /// \\end{cases}
240 /// $$
241 ///
242 /// # Worst-case complexity
243 /// Constant time and additional memory.
244 ///
245 /// # Examples
246 /// See [here](super::from#saturating_from).
247 #[inline]
248 fn saturating_from(value: $a) -> $b {
249 saturating_from_lossy(value)
250 }
251 }
252
253 impl OverflowingFrom<$a> for $b {
254 /// Converts a value to another type. If the value cannot be represented in the new
255 /// type, it is wrapped. The second component of the result indicates whether overflow
256 /// occurred.
257 ///
258 /// Let $W$ be the width of the target type.
259 ///
260 /// If the target type is unsigned, then $f_W(n) = (m, k \neq 0)$, where $m < 2^W$ and
261 /// $n + 2^W k = m$ for some $k \in \Z$.
262 ///
263 /// If the target type is signed, then $f_W(n) = (m, k \neq 0)$, where $-2^{W-1} \leq m
264 /// < 2^{W-1}$ and $n + 2^W k = m$ for some $k \in \Z$.
265 ///
266 /// # Worst-case complexity
267 /// Constant time and additional memory.
268 ///
269 /// # Examples
270 /// See [here](super::from#overflowing_from).
271 #[inline]
272 fn overflowing_from(value: $a) -> ($b, bool) {
273 overflowing_from_lossy(value)
274 }
275 }
276
277 impl ConvertibleFrom<$a> for $b {
278 /// Determines whether a value is convertible to a different type.
279 ///
280 /// Let $W$ be the width of the target type.
281 ///
282 /// If the target type is unsigned then,
283 /// $$
284 /// f_W(n) = (0 \leq n < 2^W).
285 /// $$
286 ///
287 /// If the target type is signed then,
288 /// $$
289 /// f_W(n) = (-2^{W-1} \leq n < 2^{W-1}-1).
290 /// $$
291 ///
292 /// # Worst-case complexity
293 /// Constant time and additional memory.
294 ///
295 /// # Examples
296 /// See [here](super::from#convertible_from).
297 #[inline]
298 fn convertible_from(value: $a) -> bool {
299 convertible_from_lossy::<$a, $b>(value)
300 }
301 }
302 };
303}
304
305// This macro defines conversions from type $a to type $b, where the set of values representable by
306// type $a is a proper subset of the set of values representable by type $b.
307macro_rules! proper_subset_conversion {
308 ($a:ident, $b:ident) => {
309 lossless_conversion!($a, $b);
310 lossy_conversion!($b, $a);
311 };
312}
313
314// This macro defines conversions from type $a to type $b, where the set of values representable by
315// type $a is neither a subset nor a superset of the set of values representable by type $b.
316macro_rules! no_containment_conversion {
317 ($a:ident, $b:ident) => {
318 lossy_conversion!($a, $b);
319 lossy_conversion!($b, $a);
320 };
321}
322
323apply_to_primitive_ints!(identity_conversion);
324
325proper_subset_conversion!(u8, u16);
326proper_subset_conversion!(u8, u32);
327proper_subset_conversion!(u8, u64);
328proper_subset_conversion!(u8, u128);
329proper_subset_conversion!(u8, usize);
330proper_subset_conversion!(u8, i16);
331proper_subset_conversion!(u8, i32);
332proper_subset_conversion!(u8, i64);
333proper_subset_conversion!(u8, i128);
334proper_subset_conversion!(u8, isize);
335proper_subset_conversion!(u16, u32);
336proper_subset_conversion!(u16, u64);
337proper_subset_conversion!(u16, u128);
338proper_subset_conversion!(u16, usize);
339proper_subset_conversion!(u16, i32);
340proper_subset_conversion!(u16, i64);
341proper_subset_conversion!(u16, i128);
342proper_subset_conversion!(u32, u64);
343proper_subset_conversion!(u32, u128);
344proper_subset_conversion!(u32, i64);
345proper_subset_conversion!(u32, i128);
346proper_subset_conversion!(u64, u128);
347proper_subset_conversion!(u64, i128);
348proper_subset_conversion!(i8, i16);
349proper_subset_conversion!(i8, i32);
350proper_subset_conversion!(i8, i64);
351proper_subset_conversion!(i8, i128);
352proper_subset_conversion!(i8, isize);
353proper_subset_conversion!(i16, i32);
354proper_subset_conversion!(i16, i64);
355proper_subset_conversion!(i16, i128);
356proper_subset_conversion!(i16, isize);
357proper_subset_conversion!(i32, i64);
358proper_subset_conversion!(i32, i128);
359proper_subset_conversion!(i64, i128);
360
361no_containment_conversion!(u8, i8);
362no_containment_conversion!(u16, i8);
363no_containment_conversion!(u16, i16);
364no_containment_conversion!(u16, isize);
365no_containment_conversion!(u32, usize);
366no_containment_conversion!(u32, i8);
367no_containment_conversion!(u32, i16);
368no_containment_conversion!(u32, i32);
369no_containment_conversion!(u32, isize);
370no_containment_conversion!(u64, usize);
371no_containment_conversion!(u64, i8);
372no_containment_conversion!(u64, i16);
373no_containment_conversion!(u64, i32);
374no_containment_conversion!(u64, i64);
375no_containment_conversion!(u64, isize);
376no_containment_conversion!(u128, usize);
377no_containment_conversion!(u128, i8);
378no_containment_conversion!(u128, i16);
379no_containment_conversion!(u128, i32);
380no_containment_conversion!(u128, i64);
381no_containment_conversion!(u128, i128);
382no_containment_conversion!(u128, isize);
383no_containment_conversion!(usize, i8);
384no_containment_conversion!(usize, i16);
385no_containment_conversion!(usize, i32);
386no_containment_conversion!(usize, i64);
387no_containment_conversion!(usize, i128);
388no_containment_conversion!(usize, isize);
389no_containment_conversion!(i32, isize);
390no_containment_conversion!(i64, isize);
391no_containment_conversion!(i128, isize);
392
393fn primitive_float_rounding_from_unsigned<T: PrimitiveFloat, U: PrimitiveUnsigned>(
394 value: U,
395 rm: RoundingMode,
396) -> (T, Ordering) {
397 if value == U::ZERO {
398 return (T::ZERO, Equal);
399 }
400 let (mantissa, exponent, o) = sci_mantissa_and_exponent_round(value, rm).unwrap();
401 if let Some(f) = T::from_sci_mantissa_and_exponent(mantissa, i64::wrapping_from(exponent)) {
402 (f, o)
403 } else {
404 match rm {
405 Exact => {
406 panic!("Value cannot be represented exactly as an {}", T::NAME)
407 }
408 Floor | Down | Nearest => (T::MAX_FINITE, Less),
409 _ => (T::INFINITY, Greater),
410 }
411 }
412}
413
414fn unsigned_rounding_from_primitive_float<T: PrimitiveUnsigned, U: PrimitiveFloat>(
415 value: U,
416 rm: RoundingMode,
417) -> (T, Ordering) {
418 assert!(!value.is_nan());
419 if value.is_infinite() {
420 return if value.is_sign_positive() {
421 match rm {
422 Exact => {
423 panic!("Value cannot be represented exactly as a {}", T::NAME)
424 }
425 Down | Floor | Nearest => (T::MAX, Less),
426 _ => panic!("Cannot round away from positive infinity"),
427 }
428 } else {
429 match rm {
430 Exact => {
431 panic!("Value cannot be represented exactly as a {}", T::NAME)
432 }
433 Down | Ceiling | Nearest => (T::ZERO, Greater),
434 _ => panic!("Cannot round away from negative infinity"),
435 }
436 };
437 }
438 if value == U::ZERO {
439 return (T::ZERO, Equal);
440 }
441 if value.is_sign_negative() {
442 return match rm {
443 Exact => {
444 panic!("Value cannot be represented exactly as a {}", T::NAME)
445 }
446 Ceiling | Down | Nearest => (T::ZERO, Greater),
447 _ => panic!("Value is less than 0 and rounding mode is {rm}"),
448 };
449 }
450 let (mut mantissa, exponent) = value.integer_mantissa_and_exponent();
451 let (result, o) = if exponent <= 0 {
452 let o = mantissa.shr_round_assign(-exponent, rm);
453 (T::try_from(mantissa).ok(), o)
454 } else {
455 (
456 T::try_from(mantissa)
457 .ok()
458 .and_then(|n| n.arithmetic_checked_shl(exponent)),
459 Equal,
460 )
461 };
462 if let Some(n) = result {
463 (n, o)
464 } else {
465 match rm {
466 Exact => {
467 panic!("Value cannot be represented exactly as a {}", T::NAME)
468 }
469 Floor | Down | Nearest => (T::MAX, Less),
470 _ => panic!(
471 "Value is greater than {}::MAX and rounding mode is {}",
472 T::NAME,
473 rm
474 ),
475 }
476 }
477}
478
479#[derive(Clone, Copy, Debug, Eq, PartialEq)]
480pub struct PrimitiveFloatFromUnsignedError;
481
482fn primitive_float_try_from_unsigned<T: PrimitiveFloat, U: PrimitiveUnsigned>(
483 value: U,
484) -> Result<T, PrimitiveFloatFromUnsignedError> {
485 if value == U::ZERO {
486 return Ok(T::ZERO);
487 }
488 let (mantissa, exponent, _) =
489 sci_mantissa_and_exponent_round(value, Exact).ok_or(PrimitiveFloatFromUnsignedError)?;
490 T::from_sci_mantissa_and_exponent(mantissa, i64::wrapping_from(exponent))
491 .ok_or(PrimitiveFloatFromUnsignedError)
492}
493
494#[derive(Clone, Copy, Debug, Eq, PartialEq)]
495pub enum UnsignedFromFloatError {
496 FloatInfiniteOrNan,
497 FloatNegative,
498 FloatNonIntegerOrOutOfRange,
499}
500
501fn unsigned_try_from_primitive_float<T: PrimitiveUnsigned, U: PrimitiveFloat>(
502 value: U,
503) -> Result<T, UnsignedFromFloatError> {
504 if !value.is_finite() {
505 Err(UnsignedFromFloatError::FloatInfiniteOrNan)
506 } else if value == U::ZERO {
507 Ok(T::ZERO)
508 } else if value < U::ZERO {
509 Err(UnsignedFromFloatError::FloatNegative)
510 } else {
511 let (mantissa, exponent) = value.integer_mantissa_and_exponent();
512 if exponent < 0 {
513 Err(UnsignedFromFloatError::FloatNonIntegerOrOutOfRange)
514 } else {
515 T::try_from(mantissa)
516 .or(Err(UnsignedFromFloatError::FloatNonIntegerOrOutOfRange))
517 .and_then(|n| {
518 n.arithmetic_checked_shl(exponent)
519 .ok_or(UnsignedFromFloatError::FloatNonIntegerOrOutOfRange)
520 })
521 }
522 }
523}
524
525fn primitive_float_convertible_from_unsigned<
526 T: PrimitiveFloat,
527 U: PrimitiveUnsigned + SciMantissaAndExponent<T, u64>,
528>(
529 value: U,
530) -> bool {
531 if value == U::ZERO {
532 return true;
533 }
534 let precision = (value >> value.trailing_zeros()).significant_bits();
535 precision <= T::MANTISSA_WIDTH + 1
536 && i64::wrapping_from(SciMantissaAndExponent::<T, u64>::sci_exponent(value))
537 <= T::MAX_EXPONENT
538}
539
540#[inline]
541fn unsigned_convertible_from_primitive_float<T: PrimitiveUnsigned, U: PrimitiveFloat>(
542 value: U,
543) -> bool {
544 value >= U::ZERO
545 && value.is_integer()
546 && (value == U::ZERO || value.sci_exponent() < i64::wrapping_from(T::WIDTH))
547}
548
549macro_rules! impl_from_float_unsigned {
550 ($u:ident) => {
551 macro_rules! impl_from_float_unsigned_inner {
552 ($f:ident) => {
553 impl RoundingFrom<$u> for $f {
554 /// Converts a value of an unsigned type to a value of a floating point type
555 /// according to a specified [`RoundingMode`]. An [`Ordering`] is also returned,
556 /// indicating whether the returned value is less than, equal to, or greater
557 /// than the original value.
558 ///
559 /// - If the rounding mode is `Floor` or `Down`, the largest float less than or
560 /// equal to the value is returned.
561 /// - If the rounding mode is `Ceiling` or `Up`, the smallest float greater than
562 /// or equal to the value is returned.
563 /// - If the rounding mode is `Nearest`, then the nearest float is returned. If
564 /// the value is exactly between two floats, the float with the zero
565 /// least-significant bit in its representation is selected. If the value is
566 /// larger than the maximum finite float (which can only happen when
567 /// converting a `u128` to an `f32`), the maximum finite float is returned.
568 ///
569 /// # Worst-case complexity
570 /// Constant time and additional memory.
571 ///
572 /// # Panics
573 /// Panics if `rm` is `Exact` but `value` is not exactly equal to any value of
574 /// the primitive float type.
575 ///
576 /// # Examples
577 /// See [here](super::from#rounding_from).
578 #[inline]
579 fn rounding_from(value: $u, rm: RoundingMode) -> ($f, Ordering) {
580 primitive_float_rounding_from_unsigned(value, rm)
581 }
582 }
583
584 impl RoundingFrom<$f> for $u {
585 /// Converts a value of a floating point type to a value of an unsigned type
586 /// according to a specified [`RoundingMode`]. An [`Ordering`] is also returned,
587 /// indicating whether the returned value is less than, equal to, or greater
588 /// than the original value.
589 ///
590 /// - If the rounding mode is `Floor`, the largest number less than or equal to
591 /// the value is returned. If the float is greater than the maximum
592 /// representable unsigned value, the maximum unsigned value is returned. If
593 /// the float is negative, the function panics.
594 /// - If the rounding mode is `Ceiling`, the smallest number greater than or
595 /// equal to the value is returned. If the float is negative, zero is
596 /// returned. If the float is greater than the maximum representable unsigned
597 /// value, the function panics.
598 /// - If the rounding mode is `Down`, then the rounding proceeds as with `Floor`
599 /// if the float is non-negative and as with `Ceiling` if the value is
600 /// negative.
601 /// - If the rounding mode is `Up`, then the rounding proceeds as with `Ceiling`
602 /// if the value is non-negative and as with `Floor` if the value is negative.
603 /// - If the rounding mode is `Nearest`, then the nearest value is returned. If
604 /// the value is exactly between two numbers, the even one is selected. If the
605 /// float is greater than the maximum representable unsigned value, the
606 /// maximum unsigned value is returned. If the float is negative, zero is
607 /// returned.
608 ///
609 /// # Worst-case complexity
610 /// Constant time and additional memory.
611 ///
612 /// # Panics
613 /// - If `value` is `NaN`.
614 /// - If `rm` is `Exact` but `value` is not exactly equal to any value of the
615 /// unsigned type.
616 /// - If `value` is greater than the maximum value of the unsigned type and `rm`
617 /// is `Ceiling` or `Up`.
618 /// - If `value` is negative and `rm` is `Floor` or `Up`.
619 ///
620 /// # Examples
621 /// See [here](super::from#rounding_from).
622 #[inline]
623 fn rounding_from(value: $f, rm: RoundingMode) -> ($u, Ordering) {
624 unsigned_rounding_from_primitive_float(value, rm)
625 }
626 }
627
628 impl TryFrom<$u> for NiceFloat<$f> {
629 type Error = PrimitiveFloatFromUnsignedError;
630
631 /// Converts a value of an unsigned type to a value of a floating point type,
632 /// returning an error if an exact conversion is not possible.
633 ///
634 /// The conversion succeeds if the unsigned value is not too large to represent
635 /// (which can only happen when converting a [`u128`] to an [`f32`]) and the
636 /// precision of the unsigned value is not too high.
637 ///
638 /// # Worst-case complexity
639 /// Constant time and additional memory.
640 ///
641 /// # Examples
642 /// See [here](super::from#try_from).
643 #[inline]
644 fn try_from(value: $u) -> Result<NiceFloat<$f>, Self::Error> {
645 primitive_float_try_from_unsigned(value).map(NiceFloat)
646 }
647 }
648
649 impl TryFrom<NiceFloat<$f>> for $u {
650 type Error = UnsignedFromFloatError;
651
652 /// Converts a value of a floating point type to a value of an unsigned type,
653 /// returning an error if an exact conversion is not possible.
654 ///
655 /// The conversion succeeds if the floating point value is an integer, not
656 /// negative (negative zero is ok), and not too large.
657 ///
658 /// # Worst-case complexity
659 /// Constant time and additional memory.
660 ///
661 /// # Examples
662 /// See [here](super::from#try_from).
663 #[inline]
664 fn try_from(value: NiceFloat<$f>) -> Result<$u, Self::Error> {
665 unsigned_try_from_primitive_float(value.0)
666 }
667 }
668
669 impl ConvertibleFrom<$u> for $f {
670 /// Checks whether a value of an unsigned type is convertible to a floating
671 /// point type.
672 ///
673 /// An exact conversion is possible if the unsigned value is not too large to
674 /// represent (which can only happen when converting a [`u128`] to an [`f32`])
675 /// and the precision of the unsigned value is not too high.
676 ///
677 /// # Worst-case complexity
678 /// Constant time and additional memory.
679 ///
680 /// # Examples
681 /// See [here](super::from#convertible_from).
682 #[inline]
683 fn convertible_from(value: $u) -> bool {
684 primitive_float_convertible_from_unsigned::<$f, $u>(value)
685 }
686 }
687
688 impl ConvertibleFrom<$f> for $u {
689 /// Checks whether a value of a floating point type is convertible to an
690 /// unsigned type.
691 ///
692 /// An exact conversion is possible if the floating point value is an integer,
693 /// not negative (negative zero is ok), and not too large.
694 ///
695 /// # Worst-case complexity
696 /// Constant time and additional memory.
697 ///
698 /// # Examples
699 /// See [here](super::from#convertible_from).
700 #[inline]
701 fn convertible_from(value: $f) -> bool {
702 unsigned_convertible_from_primitive_float::<$u, $f>(value)
703 }
704 }
705 };
706 }
707 apply_to_primitive_floats!(impl_from_float_unsigned_inner);
708 };
709}
710apply_to_unsigneds!(impl_from_float_unsigned);
711
712#[inline]
713fn primitive_float_rounding_from_signed<
714 U: PrimitiveUnsigned,
715 S: PrimitiveSigned + UnsignedAbs<Output = U>,
716 F: PrimitiveFloat + RoundingFrom<U>,
717>(
718 value: S,
719 rm: RoundingMode,
720) -> (F, Ordering) {
721 let abs = value.unsigned_abs();
722 if value >= S::ZERO {
723 F::rounding_from(abs, rm)
724 } else {
725 let (x, o) = F::rounding_from(abs, -rm);
726 (-x, o.reverse())
727 }
728}
729
730fn signed_rounding_from_primitive_float<
731 U: PrimitiveUnsigned + RoundingFrom<F>,
732 S: TryFrom<U> + PrimitiveSigned + UnsignedAbs<Output = U>,
733 F: PrimitiveFloat,
734>(
735 value: F,
736 rm: RoundingMode,
737) -> (S, Ordering) {
738 if value.is_infinite() {
739 return if value.is_sign_positive() {
740 match rm {
741 Exact => {
742 panic!("Value cannot be represented exactly as a {}", S::NAME)
743 }
744 Down | Floor | Nearest => (S::MAX, Less),
745 _ => panic!("Cannot round away from extreme value"),
746 }
747 } else {
748 match rm {
749 Exact => {
750 panic!("Value cannot be represented exactly as a {}", S::NAME)
751 }
752 Down | Nearest | Ceiling => (S::MIN, Greater),
753 _ => panic!("Cannot round away from extreme value"),
754 }
755 };
756 }
757 if value == F::ZERO {
758 return (S::ZERO, Equal);
759 }
760 if value.is_sign_positive() {
761 let (abs, o) = U::rounding_from(value, rm);
762 if let Ok(n) = S::try_from(abs) {
763 (n, o)
764 } else {
765 match rm {
766 Exact => {
767 panic!("Value cannot be represented exactly as an {}", S::NAME)
768 }
769 Floor | Down | Nearest => (S::MAX, Less),
770 _ => panic!(
771 "Value is greater than {}::MAX and rounding mode is {}",
772 S::NAME,
773 rm
774 ),
775 }
776 }
777 } else {
778 let (abs, o) = U::rounding_from(-value, -rm);
779 let n = if abs == S::MIN.unsigned_abs() {
780 Some(S::MIN)
781 } else {
782 S::try_from(abs).ok().map(Neg::neg)
783 };
784 if let Some(n) = n {
785 (n, o.reverse())
786 } else {
787 match rm {
788 Exact => {
789 panic!("Value cannot be represented exactly as an {}", S::NAME)
790 }
791 Ceiling | Down | Nearest => (S::MIN, Greater),
792 _ => panic!(
793 "Value is smaller than {}::MIN and rounding mode is {}",
794 S::NAME,
795 rm
796 ),
797 }
798 }
799 }
800}
801
802#[derive(Clone, Copy, Debug, Eq, PartialEq)]
803pub struct PrimitiveFloatFromSignedError;
804
805#[inline]
806fn primitive_float_try_from_signed<
807 U: PrimitiveUnsigned,
808 S: PrimitiveSigned + UnsignedAbs<Output = U>,
809 F: PrimitiveFloat,
810>(
811 value: S,
812) -> Result<F, PrimitiveFloatFromSignedError>
813where
814 NiceFloat<F>: TryFrom<U>,
815{
816 let abs = value.unsigned_abs();
817 if value >= S::ZERO {
818 NiceFloat::<F>::try_from(abs)
819 .map(|f| f.0)
820 .map_err(|_| PrimitiveFloatFromSignedError)
821 } else {
822 NiceFloat::<F>::try_from(abs)
823 .map(|f| -f.0)
824 .map_err(|_| PrimitiveFloatFromSignedError)
825 }
826}
827
828#[derive(Clone, Copy, Debug, Eq, PartialEq)]
829pub enum SignedFromFloatError {
830 FloatInfiniteOrNan,
831 FloatNonIntegerOrOutOfRange,
832}
833
834fn signed_try_from_primitive_float<
835 U: TryFrom<NiceFloat<F>> + PrimitiveUnsigned,
836 S: TryFrom<U> + PrimitiveSigned + UnsignedAbs<Output = U>,
837 F: PrimitiveFloat,
838>(
839 value: F,
840) -> Result<S, SignedFromFloatError> {
841 if !value.is_finite() {
842 return Err(SignedFromFloatError::FloatInfiniteOrNan);
843 }
844 if value >= F::ZERO {
845 S::try_from(
846 U::try_from(NiceFloat(value))
847 .or(Err(SignedFromFloatError::FloatNonIntegerOrOutOfRange))?,
848 )
849 .or(Err(SignedFromFloatError::FloatNonIntegerOrOutOfRange))
850 } else {
851 let abs = U::try_from(NiceFloat(-value))
852 .or(Err(SignedFromFloatError::FloatNonIntegerOrOutOfRange))?;
853 if abs == S::MIN.unsigned_abs() {
854 Ok(S::MIN)
855 } else {
856 S::try_from(abs)
857 .map(Neg::neg)
858 .or(Err(SignedFromFloatError::FloatNonIntegerOrOutOfRange))
859 }
860 }
861}
862
863#[inline]
864fn primitive_float_convertible_from_signed<
865 U: PrimitiveUnsigned,
866 S: PrimitiveSigned + UnsignedAbs<Output = U>,
867 F: ConvertibleFrom<U> + PrimitiveFloat,
868>(
869 value: S,
870) -> bool {
871 F::convertible_from(value.unsigned_abs())
872}
873
874fn signed_convertible_from_primitive_float<U: PrimitiveUnsigned, F: PrimitiveFloat>(
875 value: F,
876) -> bool {
877 if !value.is_integer() {
878 return false;
879 }
880 if value >= F::ZERO {
881 value == F::ZERO || value.sci_exponent() < i64::wrapping_from(U::WIDTH) - 1
882 } else {
883 let exponent = value.sci_exponent();
884 let limit = i64::wrapping_from(U::WIDTH) - 1;
885 value == F::ZERO
886 || exponent < limit
887 || exponent == limit
888 && value == -F::from_sci_mantissa_and_exponent(F::ONE, exponent).unwrap()
889 }
890}
891
892macro_rules! impl_from_float_signed {
893 ($u:ident, $i:ident) => {
894 macro_rules! impl_from_float_signed_inner {
895 ($f:ident) => {
896 impl RoundingFrom<$i> for $f {
897 /// Converts a value of a signed type to a value of a floating point type
898 /// according to a specified [`RoundingMode`]. An [`Ordering`] is also returned,
899 /// indicating whether the returned value is less than, equal to, or greater
900 /// than the original value.
901 ///
902 /// - If the rounding mode is `Floor`, the largest float less than or equal to
903 /// the value is returned.
904 /// - If the rounding mode is `Ceiling`, the smallest float greater than or
905 /// equal to the value is returned.
906 /// - If the rounding mode is `Down`, then the rounding proceeds as with `Floor`
907 /// if the value is non-negative and as with `Ceiling` if the value is
908 /// negative.
909 /// - If the rounding mode is `Up`, then the rounding proceeds as with `Ceiling`
910 /// if the value is non-negative and as with `Floor` if the value is negative.
911 /// - If the rounding mode is `Nearest`, then the nearest float is returned. If
912 /// the value is exactly between two floats, the float with the zero
913 /// least-significant bit in its representation is selected.
914 ///
915 /// # Worst-case complexity
916 /// Constant time and additional memory.
917 ///
918 /// # Panics
919 /// Panics if `rm` is `Exact` but `value` is not exactly equal to any value of
920 /// the primitive float type.
921 ///
922 /// # Examples
923 /// See [here](super::from#rounding_from).
924 #[inline]
925 fn rounding_from(value: $i, rm: RoundingMode) -> ($f, Ordering) {
926 primitive_float_rounding_from_signed::<$u, $i, $f>(value, rm)
927 }
928 }
929
930 impl RoundingFrom<$f> for $i {
931 /// Converts a value of a floating point type to a value of a signed type
932 /// according to a specified [`RoundingMode`]. An [`Ordering`] is also returned,
933 /// indicating whether the returned value is less than, equal to, or greater
934 /// than the original value.
935 ///
936 /// - If the rounding mode is `Floor`, the largest number less than or equal to
937 /// the value is returned. If the float is greater than the maximum
938 /// representable signed value, the maximum signed value is returned. If the
939 /// float is smaller than the minimum representable signed value, the function
940 /// panics.
941 /// - If the rounding mode is `Ceiling`, the smallest number greater than or
942 /// equal to the value is returned. If the float is smaller than the minimum
943 /// representable signed value, the minimum signed value is returned. If the
944 /// float is greater than the maximum representable signed value, the function
945 /// panics.
946 /// - If the rounding mode is `Down`, then the rounding proceeds as with `Floor`
947 /// if the float is non-negative and as with `Ceiling` if the value is
948 /// negative.
949 /// - If the rounding mode is `Up`, then the rounding proceeds as with `Ceiling`
950 /// if the value is non-negative and as with `Floor` if the value is negative.
951 /// - If the rounding mode is `Nearest`, then the nearest value is returned. If
952 /// the value is exactly between two numbers, the even one is selected. If the
953 /// float is greater than the maximum representable signed value, the maximum
954 /// signed value is returned. If the float is smaller than the minimum
955 /// representable signed value, the minimum signed value is returned.
956 ///
957 /// # Worst-case complexity
958 /// Constant time and additional memory.
959 ///
960 /// # Panics
961 /// - If `value` is `NaN`.
962 /// - If `rm` is `Exact` but `value` is not exactly equal to any value of the
963 /// unsigned type.
964 /// - If `value` is greater than the maximum value of the signed type and `rm`
965 /// is `Ceiling` or `Up`.
966 /// - If `value` is smaller than the minimum value of the signed type and `rm`
967 /// is `Floor` or `Up`.
968 ///
969 /// # Examples
970 /// See [here](super::from#rounding_from).
971 #[inline]
972 fn rounding_from(value: $f, rm: RoundingMode) -> ($i, Ordering) {
973 signed_rounding_from_primitive_float::<$u, $i, $f>(value, rm)
974 }
975 }
976
977 impl TryFrom<$i> for NiceFloat<$f> {
978 type Error = PrimitiveFloatFromSignedError;
979
980 /// Converts a value of a signed type to a value of a floating point type,
981 /// returning an error if an exact conversion is not possible.
982 ///
983 /// The conversion succeeds if the precision of the signed value is not too
984 /// high.
985 ///
986 /// # Worst-case complexity
987 /// Constant time and additional memory.
988 ///
989 /// # Examples
990 /// See [here](super::from#try_from).
991 #[inline]
992 fn try_from(value: $i) -> Result<NiceFloat<$f>, Self::Error> {
993 primitive_float_try_from_signed(value).map(NiceFloat)
994 }
995 }
996
997 impl TryFrom<NiceFloat<$f>> for $i {
998 type Error = SignedFromFloatError;
999
1000 /// Converts a value of a floating point type to a value of a signed type,
1001 /// returning an error if an exact conversion is not possible.
1002 ///
1003 /// The conversion succeeds if the floating point value is an integer and not
1004 /// too large or too small.
1005 ///
1006 /// # Worst-case complexity
1007 /// Constant time and additional memory.
1008 ///
1009 /// # Examples
1010 /// See [here](super::from#try_from).
1011 #[inline]
1012 fn try_from(value: NiceFloat<$f>) -> Result<$i, Self::Error> {
1013 signed_try_from_primitive_float::<$u, $i, $f>(value.0)
1014 }
1015 }
1016
1017 impl ConvertibleFrom<$i> for $f {
1018 /// Checks whether a value of a signed type is convertible to a floating point
1019 /// type.
1020 ///
1021 /// An exact conversion is possible if the precision of the signed value is not
1022 /// too high.
1023 ///
1024 /// # Worst-case complexity
1025 /// Constant time and additional memory.
1026 ///
1027 /// # Examples
1028 /// See [here](super::from#convertible_from).
1029 #[inline]
1030 fn convertible_from(value: $i) -> bool {
1031 primitive_float_convertible_from_signed::<$u, $i, $f>(value)
1032 }
1033 }
1034
1035 impl ConvertibleFrom<$f> for $i {
1036 /// Checks whether a value of a floating point type is convertible to a signed
1037 /// type.
1038 ///
1039 /// An exact conversion is possible if the floating point value is an integer
1040 /// and not too large or too small.
1041 ///
1042 /// # Worst-case complexity
1043 /// Constant time and additional memory.
1044 ///
1045 /// # Examples
1046 /// See [here](super::from#convertible_from).
1047 #[inline]
1048 fn convertible_from(value: $f) -> bool {
1049 signed_convertible_from_primitive_float::<$u, $f>(value)
1050 }
1051 }
1052 };
1053 }
1054 apply_to_primitive_floats!(impl_from_float_signed_inner);
1055 };
1056}
1057apply_to_unsigned_signed_pairs!(impl_from_float_signed);