malachite_base/num/conversion/
is_integer.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::basic::floats::PrimitiveFloat;
10use crate::num::conversion::traits::{IsInteger, WrappingFrom};
11use crate::num::logic::traits::TrailingZeros;
12
13fn is_integer_float<T: PrimitiveFloat>(x: T) -> bool {
14    if x.is_nan() || x.is_infinite() {
15        false
16    } else if x == T::ZERO {
17        true
18    } else {
19        let (raw_mantissa, raw_exponent) = x.raw_mantissa_and_exponent();
20        raw_exponent != 0
21            && i64::wrapping_from(
22                raw_exponent
23                    + if raw_mantissa == 0 {
24                        T::MANTISSA_WIDTH
25                    } else {
26                        TrailingZeros::trailing_zeros(raw_mantissa)
27                    },
28            ) > -T::MIN_EXPONENT
29    }
30}
31
32macro_rules! impl_is_integer_primitive_int {
33    ($t:ident) => {
34        impl IsInteger for $t {
35            /// Determines whether a value is an integer.
36            ///
37            /// For primitive integer types this always returns `true`.
38            ///
39            /// $f(x) = \textrm{true}$.
40            ///
41            /// # Worst-case complexity
42            /// Constant time and additional memory.
43            ///
44            /// # Examples
45            /// See [here](super::is_integer#is_integer).
46            #[inline]
47            fn is_integer(self) -> bool {
48                true
49            }
50        }
51    };
52}
53apply_to_primitive_ints!(impl_is_integer_primitive_int);
54
55macro_rules! impl_is_integer_primitive_float {
56    ($t:ident) => {
57        impl IsInteger for $t {
58            /// Determines whether a value is an integer.
59            ///
60            /// $f(x) = (x \in \Z)$.
61            ///
62            /// # Worst-case complexity
63            /// Constant time and additional memory.
64            ///
65            /// # Examples
66            /// See [here](super::is_integer#is_integer).
67            #[inline]
68            fn is_integer(self) -> bool {
69                is_integer_float(self)
70            }
71        }
72    };
73}
74apply_to_primitive_floats!(impl_is_integer_primitive_float);