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);