1#![deny(rustdoc::broken_intra_doc_links)]
2
3use crate::{
22 core::{errors::capture_backtrace, policies::StrictFinitePolicy},
23 functions::FunctionErrors,
24 kernels::{RawComplexTrait, RawRealTrait, RawScalarTrait},
25};
26use duplicate::duplicate_item;
27use num::Complex;
28use std::backtrace::Backtrace;
29use thiserror::Error;
30use try_create::ValidationPolicy;
31
32#[duplicate_item(
36 enum_name enum_doc;
37 [CosInputErrors] ["Errors that can occur during the input validation phase when computing the *cosine* of a real or complex number.\n\nThis enum is used as a source for the `Input` variant of [`CosErrors`].\n\n# Type Parameters\n\n- `RawScalar`: A type that implements the [`RawScalarTrait`] trait. This type parameter is used to specify the numeric type for the computation and its associated raw error type `RawScalar::ValidationErrors` (e.g., [`crate::core::errors::ErrorsValidationRawReal`], [`crate::core::errors::ErrorsValidationRawComplex`], etc.).\n\n# Variants\n\n- `InvalidArgument`: Indicates that the input argument failed general validation checks (e.g., NaN, Infinity). The `source` field provides the specific raw validation error."];
38 [SinInputErrors] ["Errors that can occur during the input validation phase when computing the *sine* of a real or complex number.\n\nThis enum is used as a source for the `Input` variant of [`SinErrors`].\n\n# Type Parameters\n\n- `RawScalar`: A type that implements the [`RawScalarTrait`] trait. This type parameter is used to specify the numeric type for the computation and its associated raw error type `RawScalar::ValidationErrors` (e.g., [`crate::core::errors::ErrorsValidationRawReal`], [`crate::core::errors::ErrorsValidationRawComplex`], etc.).\n\n# Variants\n\n- `InvalidArgument`: Indicates that the input argument failed general validation checks (e.g., NaN, Infinity). The `source` field provides the specific raw validation error."];
39)]
40#[derive(Debug, Error)]
41#[doc = enum_doc]
42pub enum enum_name<RawScalar: RawScalarTrait> {
43 #[error("the argument of the function is invalid!")]
48 InvalidArgument {
49 #[source]
51 #[backtrace]
52 source: RawScalar::ValidationErrors,
53 },
54}
55
56#[derive(Debug, Error)]
73pub enum TanRealInputErrors<RawReal: RawRealTrait> {
74 #[error("the argument ({value}) is a mathematical pole for the tangent function!")]
76 ArgumentIsPole {
77 value: RawReal,
79 backtrace: Backtrace,
81 },
82
83 #[error("the argument of the function is invalid!")]
88 InvalidArgument {
89 #[source]
91 #[backtrace]
92 source: <RawReal as RawScalarTrait>::ValidationErrors,
93 },
94}
95
96#[derive(Debug, Error)]
107pub enum ATanRealInputErrors<RawReal: RawRealTrait> {
108 #[error("the argument of the function is invalid!")]
113 InvalidArgument {
114 #[source]
116 #[backtrace]
117 source: RawReal::ValidationErrors,
118 },
119}
120
121#[duplicate_item(
125 enum_name enum_doc;
126 [ASinRealInputErrors] ["Errors that can occur during the input validation phase when computing the *inverse sine* of a *real number*.\n\nThis enum is used as a source for the `Input` variant of [`ASinRealErrors`].\n\n# Type Parameters\n\n- `RawReal`: A type that implements the [`RawRealTrait`] trait. This type parameter is used to specify the numeric type for the computation and its associated raw error type `<RawReal as RawScalarTrait>::ValidationErrors` (e.g., [`crate::core::errors::ErrorsValidationRawReal<f64>`]).\n\n# Variants\n\n- `OutOfDomain`: Indicates the input argument is outside the valid domain `[-1, 1]`.\n- `InvalidArgument`: Indicates that the input argument failed general validation checks (e.g., NaN, Infinity). The `source` field provides the specific raw validation error."];
127 [ACosRealInputErrors] ["Errors that can occur during the input validation phase when computing the *inverse cosine* of a *real number*.\n\nThis enum is used as a source for the `Input` variant of [`ACosRealErrors`].\n\n# Type Parameters\n\n- `RawReal`: A type that implements the [`RawRealTrait`] trait. This type parameter is used to specify the numeric type for the computation and its associated raw error type `<RawReal as RawScalarTrait>::ValidationErrors` (e.g., [`crate::core::errors::ErrorsValidationRawReal<f64>`]).\n\n# Variants\n\n- `OutOfDomain`: Indicates the input argument is outside the valid domain `[-1, 1]`.\n- `InvalidArgument`: Indicates that the input argument failed general validation checks (e.g., NaN, Infinity). The `source` field provides the specific raw validation error."];
128)]
129#[derive(Debug, Error)]
130#[doc = enum_doc]
131pub enum enum_name<RawReal: RawRealTrait> {
132 #[error("the argument of the function ({value}) is not in the domain [-1.,1.]!")]
134 OutOfDomain {
135 value: RawReal,
137
138 backtrace: Backtrace,
140 },
141
142 #[error("the argument of the function is invalid!")]
147 InvalidArgument {
148 #[source]
150 #[backtrace]
151 source: <RawReal as RawScalarTrait>::ValidationErrors,
152 },
153}
154
155#[duplicate_item(
159 enum_name ErrIn enum_doc;
160 [CosErrors] [CosInputErrors] ["A type alias for [`FunctionErrors`], specialized for errors during *cosine* computation on a real or complex number.\n\nRepresents failures from [`Cos::try_cos()`].\n\n# Type Parameters\n\n- `RawScalar`: Implements [`RawScalarTrait`]. Defines input error type via `ErrIn<RawScalar>` and output raw error via `RawScalar::ValidationErrors`.\n\n# Variants\n\n- `Input { source: ErrIn<RawScalar> }`: Input was invalid (e.g., NaN, Infinity).\n- `Output { source: RawScalar::ValidationErrors }`: Computed output was invalid (e.g., NaN, Infinity)."];
161 [SinErrors] [SinInputErrors] ["A type alias for [`FunctionErrors`], specialized for errors during *sine* computation on a real or complex number.\n\nRepresents failures from [`Sin::try_sin()`].\n\n# Type Parameters\n\n- `RawScalar`: Implements [`RawScalarTrait`]. Defines input error type via `ErrIn<RawScalar>` and output raw error via `RawScalar::ValidationErrors`.\n\n# Variants\n\n- `Input { source: ErrIn<RawScalar> }`: Input was invalid (e.g., NaN, Infinity).\n- `Output { source: RawScalar::ValidationErrors }`: Computed output was invalid (e.g., NaN, Infinity)."];
162)]
163#[doc = enum_doc]
164pub type enum_name<RawScalar> =
165 FunctionErrors<ErrIn<RawScalar>, <RawScalar as RawScalarTrait>::ValidationErrors>;
166
167#[duplicate_item(
171 enum_name ErrIn enum_doc;
172 [ACosRealErrors] [ACosRealInputErrors] ["A type alias for [`FunctionErrors`], specialized for errors during *inverse cosine* computation on a *real number*.\n\nRepresents failures from [`ACos::try_acos()`].\n\n# Type Parameters\n\n- `RawReal`: Implements [`RawRealTrait`]. Defines input error type via `ErrIn<RawReal>` and output raw error via `<RawReal as RawScalarTrait>::ValidationErrors`.\n\n# Variants\n\n- `Input { source: ErrIn<RawReal> }`: Input was invalid (e.g., out of domain `[-1,1]`, NaN, Infinity).\n- `Output { source: <RawReal as RawScalarTrait>::ValidationErrors }`: Computed output was invalid (e.g., NaN, Infinity)."];
173 [ASinRealErrors] [ASinRealInputErrors] ["A type alias for [`FunctionErrors`], specialized for errors during *inverse sine* computation on a *real number*.\n\nRepresents failures from [`ASin::try_asin()`].\n\n# Type Parameters\n\n- `RawReal`: Implements [`RawRealTrait`]. Defines input error type via `ErrIn<RawReal>` and output raw error via `<RawReal as RawScalarTrait>::ValidationErrors`.\n\n# Variants\n\n- `Input { source: ErrIn<RawReal> }`: Input was invalid (e.g., out of domain `[-1,1]`, NaN, Infinity).\n- `Output { source: <RawReal as RawScalarTrait>::ValidationErrors }`: Computed output was invalid (e.g., NaN, Infinity)."];
174 [ATanRealErrors] [ATanRealInputErrors] ["A type alias for [`FunctionErrors`], specialized for errors during *inverse tangent* computation on a *real number*.\n\nRepresents failures from [`ATan::try_atan()`].\n\n# Type Parameters\n\n- `RawReal`: Implements [`RawRealTrait`]. Defines input error type via `ErrIn<RawReal>` and output raw error via `<RawReal as RawScalarTrait>::ValidationErrors`.\n\n# Variants\n\n- `Input { source: ErrIn<RawReal> }`: Input was invalid (e.g., NaN, Infinity).\n- `Output { source: <RawReal as RawScalarTrait>::ValidationErrors }`: Computed output was invalid (e.g., NaN, Infinity)."];
175 [TanRealErrors] [TanRealInputErrors] ["A type alias for [`FunctionErrors`], specialized for errors during *tangent* computation on a *real number*.\n\nRepresents failures from [`Tan::try_tan()`].\n\n# Type Parameters\n\n- `RawReal`: Implements [`RawRealTrait`]. Defines input error type via `ErrIn<RawReal>` and output raw error via `<RawReal as RawScalarTrait>::ValidationErrors`.\n\n# Variants\n\n- `Input { source: ErrIn<RawReal> }`: Input was invalid (e.g., NaN, Infinity).\n- `Output { source: <RawReal as RawScalarTrait>::ValidationErrors }`: Computed output was invalid (e.g., NaN, Infinity)."];
176)]
177#[doc = enum_doc]
178pub type enum_name<RawReal> =
179 FunctionErrors<ErrIn<RawReal>, <RawReal as RawScalarTrait>::ValidationErrors>;
180
181#[duplicate_item(
185 enum_name enum_doc;
186 [ACosComplexInputErrors] ["Errors that can occur during the input validation phase when computing the *inverse cosine* of a *complex number*.\n\nThis enum is used as a source for the `Input` variant of [`ACosComplexErrors`].\n\n# Type Parameters\n\n- `RawComplex`: A type that implements the [`RawComplexTrait`] trait. This type parameter is used to specify the numeric type for the computation and its associated raw error type `<RawComplex as RawScalarTrait>::ValidationErrors`.\n\n# Variants\n\n- `InvalidArgument`: Indicates that the input argument failed general validation checks (e.g., components are NaN, Infinity). The `source` field provides the specific raw validation error."];
187 [ASinComplexInputErrors] ["Errors that can occur during the input validation phase when computing the *inverse sine* of a *complex number*.\n\nThis enum is used as a source for the `Input` variant of [`ASinComplexErrors`].\n\n# Type Parameters\n\n- `RawComplex`: A type that implements the [`RawComplexTrait`] trait. This type parameter is used to specify the numeric type for the computation and its associated raw error type `<RawComplex as RawScalarTrait>::ValidationErrors`.\n\n# Variants\n\n- `InvalidArgument`: Indicates that the input argument failed general validation checks (e.g., components are NaN, Infinity). The `source` field provides the specific raw validation error."];
188 [TanComplexInputErrors] ["Errors that can occur during the input validation phase when computing the *tangent* of a *complex number*.\n\nThis enum is used as a source for the `Input` variant of [`TanComplexErrors`].\n\n# Type Parameters\n\n- `RawComplex`: A type that implements the [`RawComplexTrait`] trait. This type parameter is used to specify the numeric type for the computation and its associated raw error type `<RawComplex as RawScalarTrait>::ValidationErrors`.\n\n# Variants\n\n- `InvalidArgument`: Indicates that the input argument failed general validation checks (e.g., components are NaN, Infinity). The `source` field provides the specific raw validation error."];
189)]
190#[derive(Debug, Error)]
191#[doc = enum_doc]
192pub enum enum_name<RawComplex: RawComplexTrait> {
193 #[error("the argument of the function is invalid!")]
198 InvalidArgument {
199 #[source]
201 #[backtrace]
202 source: <RawComplex as RawScalarTrait>::ValidationErrors,
203 },
204}
205
206#[derive(Debug, Error)]
218pub enum ATanComplexInputErrors<RawComplex: RawComplexTrait> {
219 #[error("the argument ({value:?}) is a pole for the function!")]
223 ArgumentIsPole {
224 value: RawComplex,
226
227 backtrace: std::backtrace::Backtrace,
229 },
230
231 #[error("the argument of the function is invalid!")]
236 InvalidArgument {
237 #[source]
239 #[backtrace]
240 source: <RawComplex as RawScalarTrait>::ValidationErrors,
241 },
242}
243
244#[duplicate_item(
248 enum_name ErrIn enum_doc;
249 [ACosComplexErrors] [ACosComplexInputErrors] ["A type alias for [`FunctionErrors`], specialized for errors during *inverse cosine* computation on a *complex number*.\n\nRepresents failures from [`ACos::try_acos()`].\n\n# Type Parameters\n\n- `RawComplex`: Implements [`RawComplexTrait`]. Defines input error type via `ErrIn<RawComplex>` and output raw error via `<RawComplex as RawScalarTrait>::ValidationErrors`.\n\n# Variants\n\n- `Input { source: ErrIn<RawComplex> }`: Input was invalid (e.g., components are NaN, Infinity).\n- `Output { source: <RawComplex as RawScalarTrait>::ValidationErrors }`: Computed output was invalid (e.g., components are NaN, Infinity)."];
250 [ASinComplexErrors] [ASinComplexInputErrors] ["A type alias for [`FunctionErrors`], specialized for errors during *inverse sine* computation on a *complex number*.\n\nRepresents failures from [`ASin::try_asin()`].\n\n# Type Parameters\n\n- `RawComplex`: Implements [`RawComplexTrait`]. Defines input error type via `ErrIn<RawComplex>` and output raw error via `<RawComplex as RawScalarTrait>::ValidationErrors`.\n\n# Variants\n\n- `Input { source: ErrIn<RawComplex> }`: Input was invalid (e.g., components are NaN, Infinity).\n- `Output { source: <RawComplex as RawScalarTrait>::ValidationErrors }`: Computed output was invalid (e.g., components are NaN, Infinity)."];
251 [TanComplexErrors] [TanComplexInputErrors] ["A type alias for [`FunctionErrors`], specialized for errors during *tangent* computation on a *complex number*.\n\nRepresents failures from [`Tan::try_tan()`].\n\n# Type Parameters\n\n- `RawComplex`: Implements [`RawComplexTrait`]. Defines input error type via `ErrIn<RawComplex>` and output raw error via `<RawComplex as RawScalarTrait>::ValidationErrors`.\n\n# Variants\n\n- `Input { source: ErrIn<RawComplex> }`: Input was invalid (e.g., components are NaN, Infinity).\n- `Output { source: <RawComplex as RawScalarTrait>::ValidationErrors }`: Computed output was invalid (e.g., components are NaN, Infinity)."];
252 [ATanComplexErrors] [ATanComplexInputErrors] ["A type alias for [`FunctionErrors`], specialized for errors during *inverse tangent* computation on a *complex number*.\n\nRepresents failures from [`ATan::try_atan()`].\n\n# Type Parameters\n\n- `RawComplex`: Implements [`RawComplexTrait`]. Defines input error type via `ErrIn<RawComplex>` and output raw error via `<RawComplex as RawScalarTrait>::ValidationErrors`.\n\n# Variants\n\n- `Input { source: ErrIn<RawComplex> }`: Input was invalid (e.g., components are NaN, Infinity, or a pole like `0 +/- 1i`).\n- `Output { source: <RawComplex as RawScalarTrait>::ValidationErrors }`: Computed output was invalid (e.g., components are NaN, Infinity)."];
253)]
254#[doc = enum_doc]
255pub type enum_name<RawComplex> =
256 FunctionErrors<ErrIn<RawComplex>, <RawComplex as RawScalarTrait>::ValidationErrors>;
257
258#[duplicate_item(
262 T try_func func trait_doc try_func_doc func_doc err_doc;
263 [ACos] [try_acos] [acos] ["Trait for computing the *inverse cosine* of a number.\n\nThis trait defines methods for computing the *inverse cosine* of a number. Provides both a fallible method that returns a [`Result`] and a panicking method that directly returns the computed value or panics on invalid input.\n\n# Associated Types\n\n- `Error`: The error type that is returned by the `try_acos` method. This type must implement the [`std::error::Error`] trait.\n\n# Required Methods\n\n - `try_acos`: Computes the inverse cosine of the number and returns a [`Result`]. If the computation is successful, it returns [`Ok`] with the computed value. If an error occurs, it returns [`Err`] with the associated error.\n\n - `acos`: Computes the inverse cosine of the number and directly returns the computed value. In Debug mode this method may panic if the computation fails."] ["Computes the *inverse cosine* of `self` and returns a [`Result`].\n\nIf the computation is successful, it returns [`Ok`] with the computed value. If an error occurs, it returns [`Err`] with the associated error.\n\n# Errors\n\nThis method returns an error if the computation fails. The error type is defined by the associated [`Error`] type."] ["Computes and returns the *inverse cosine* of `self`.\n\nIn Debug mode this method may panic if the computation fails.\n\n# Panics\n\nIn Debug mode this method may panic if the computation fails. It is recommended to use the `try_acos` method for safe computations."] ["The error type that is returned by the `try_acos` method."];
264 [ASin] [try_asin] [asin] ["Trait for computing the *inverse sine* of a number.\n\nThis trait defines methods for computing the *inverse sine* of a number. Provides both a fallible method that returns a [`Result`] and a panicking method that directly returns the computed value or panics on invalid input.\n\n# Associated Types\n\n- `Error`: The error type that is returned by the `try_asin` method. This type must implement the [`std::error::Error`] trait.\n\n# Required Methods\n\n - `try_asin`: Computes the inverse sine of the number and returns a [`Result`]. If the computation is successful, it returns [`Ok`] with the computed value. If an error occurs, it returns [`Err`] with the associated error.\n\n - `asin`: Computes the inverse sine of the number and directly returns the computed value. In Debug mode this method may panic if the computation fails."] ["Computes the *inverse sine* of `self` and returns a [`Result`].\n\nIf the computation is successful, it returns [`Ok`] with the computed value. If an error occurs, it returns [`Err`] with the associated error.\n\n# Errors\n\nThis method returns an error if the computation fails. The error type is defined by the associated [`Error`] type."] ["Computes and returns the *inverse sine* of `self`.\n\nIn Debug mode this method may panic if the computation fails.\n\n# Panics\n\nIn Debug mode this method may panic if the computation fails. It is recommended to use the `try_asin` method for safe computations."] ["The error type that is returned by the `try_asin` method."];
265 [ATan] [try_atan] [atan] ["Trait for computing the *inverse tangent* of a number.\n\nThis trait defines methods for computing the *inverse tangent* of a number. Provides both a fallible method that returns a [`Result`] and a panicking method that directly returns the computed value or panics on invalid input.\n\n# Associated Types\n\n- `Error`: The error type that is returned by the `try_atan` method. This type must implement the [`std::error::Error`] trait.\n\n# Required Methods\n\n - `try_atan`: Computes the inverse tangent of the number and returns a [`Result`]. If the computation is successful, it returns [`Ok`] with the computed value. If an error occurs, it returns [`Err`] with the associated error.\n\n - `atan`: Computes the inverse tangent of the number and directly returns the computed value. In Debug mode this method may panic if the computation fails."] ["Computes the *inverse tangent* of `self` and returns a [`Result`].\n\nIf the computation is successful, it returns [`Ok`] with the computed value. If an error occurs, it returns [`Err`] with the associated error.\n\n# Errors\n\nThis method returns an error if the computation fails. The error type is defined by the associated [`Error`] type."] ["Computes and returns the *inverse tangent* of `self`.\n\nIn Debug mode this method may panic if the computation fails.\n\n# Panics\n\nIn Debug mode this method may panic if the computation fails. It is recommended to use the `try_atan` method for safe computations."] ["The error type that is returned by the `try_atan` method."];
266 [Cos] [try_cos] [cos] ["Trait for computing the *cosine* of a number.\n\nThis trait defines methods for computing the *cosine* of a number. Provides both a fallible method that returns a [`Result`] and a panicking method that directly returns the computed value or panics on invalid input.\n\n# Associated Types\n\n- `Error`: The error type that is returned by the `try_cos` method. This type must implement the [`std::error::Error`] trait.\n\n# Required Methods\n\n - `try_cos`: Computes the cosine of the number and returns a [`Result`]. If the computation is successful, it returns [`Ok`] with the computed value. If an error occurs, it returns [`Err`] with the associated error.\n\n - `cos`: Computes the cosine of the number and directly returns the computed value. In Debug mode this method may panic if the computation fails."] ["Computes the *cosine* of `self` and returns a [`Result`].\n\nIf the computation is successful, it returns [`Ok`] with the computed value. If an error occurs, it returns [`Err`] with the associated error.\n\n# Errors\n\nThis method returns an error if the computation fails. The error type is defined by the associated [`Error`] type."] ["Computes and returns the *cosine* of `self`.\n\nIn Debug mode this method may panic if the computation fails.\n\n# Panics\n\nIn Debug mode this method may panic if the computation fails. It is recommended to use the `try_cos` method for safe computations."] ["The error type that is returned by the `try_cos` method."];
267 [Sin] [try_sin] [sin] ["Trait for computing the *sine* of a number.\n\nThis trait defines methods for computing the *sine* of a number. Provides both a fallible method that returns a [`Result`] and a panicking method that directly returns the computed value or panics on invalid input.\n\n# Associated Types\n\n- `Error`: The error type that is returned by the `try_sin` method. This type must implement the [`std::error::Error`] trait.\n\n# Required Methods\n\n - `try_sin`: Computes the sine of the number and returns a [`Result`]. If the computation is successful, it returns [`Ok`] with the computed value. If an error occurs, it returns [`Err`] with the associated error.\n\n - `sin`: Computes the sine of the number and directly returns the computed value. In Debug mode this method may panic if the computation fails."] ["Computes the *sine* of `self` and returns a [`Result`].\n\nIf the computation is successful, it returns [`Ok`] with the computed value. If an error occurs, it returns [`Err`] with the associated error.\n\n# Errors\n\nThis method returns an error if the computation fails. The error type is defined by the associated [`Error`] type."] ["Computes and returns the *sine* of `self`.\n\nIn Debug mode this method may panic if the computation fails.\n\n# Panics\n\nIn Debug mode this method may panic if the computation fails. It is recommended to use the `try_sin` method for safe computations."] ["The error type that is returned by the `try_sin` method."];
268 [Tan] [try_tan] [tan] ["Trait for computing the *tangent* of a number.\n\nThis trait defines methods for computing the *tangent* of a number. Provides both a fallible method that returns a [`Result`] and a panicking method that directly returns the computed value or panics on invalid input.\n\n# Associated Types\n\n- `Error`: The error type that is returned by the `try_tan` method. This type must implement the [`std::error::Error`] trait.\n\n# Required Methods\n\n - `try_tan`: Computes the tangent of the number and returns a [`Result`]. If the computation is successful, it returns [`Ok`] with the computed value. If an error occurs, it returns [`Err`] with the associated error.\n\n - `tan`: Computes the tangent of the number and directly returns the computed value. In Debug mode this method may panic if the computation fails."] ["Computes the *tangent* of `self` and returns a [`Result`].\n\nIf the computation is successful, it returns [`Ok`] with the computed value. If an error occurs, it returns [`Err`] with the associated error.\n\n# Errors\n\nThis method returns an error if the computation fails. The error type is defined by the associated [`Error`] type."] ["Computes and returns the *tangent* of `self`.\n\nIn Debug mode this method may panic if the computation fails.\n\n# Panics\n\nIn Debug mode this method may panic if the computation fails. It is recommended to use the `try_tan` method for safe computations."] ["The error type that is returned by the `try_tan` method."];
269)]
270#[doc = trait_doc]
271pub trait T: Sized {
272 #[doc = err_doc]
273 type Error: std::error::Error;
274
275 #[doc = try_func_doc]
276 #[must_use = "this `Result` may contain an error that should be handled"]
277 fn try_func(self) -> Result<Self, <Self as T>::Error>;
278
279 #[doc = func_doc]
280 fn func(self) -> Self;
281}
282
283#[duplicate_item(
284 T trait_name Err ErrIn try_func func;
285 [f64] [Sin] [SinErrors] [SinInputErrors] [try_sin] [sin];
286 [f64] [Cos] [CosErrors] [CosInputErrors] [try_cos] [cos];
287 [f64] [ATan] [ATanRealErrors] [ATanRealInputErrors] [try_atan] [atan];
288 [Complex::<f64>] [Sin] [SinErrors] [SinInputErrors] [try_sin] [sin];
289 [Complex::<f64>] [Cos] [CosErrors] [CosInputErrors] [try_cos] [cos];
290 [Complex::<f64>] [Tan] [TanComplexErrors] [TanComplexInputErrors] [try_tan] [tan];
291 [Complex::<f64>] [ASin] [ASinComplexErrors] [ASinComplexInputErrors] [try_asin] [asin];
292 [Complex::<f64>] [ACos] [ACosComplexErrors] [ACosComplexInputErrors] [try_acos] [acos];
293
294)]
295impl trait_name for T {
296 type Error = Err<T>;
297
298 #[inline(always)]
299 fn try_func(self) -> Result<Self, Self::Error> {
300 StrictFinitePolicy::<T, 53>::validate(self)
301 .map_err(|e| ErrIn::InvalidArgument { source: e }.into())
302 .and_then(|v| {
303 StrictFinitePolicy::<T, 53>::validate(T::func(v))
304 .map_err(|e| Err::Output { source: e })
305 })
306 }
307
308 #[inline(always)]
309 fn func(self) -> Self {
310 #[cfg(debug_assertions)]
311 {
312 self.try_func().unwrap()
313 }
314 #[cfg(not(debug_assertions))]
315 {
316 T::func(self)
317 }
318 }
319}
320
321impl Tan for f64 {
322 type Error = TanRealErrors<f64>;
323
324 #[inline(always)]
325 fn try_tan(self) -> Result<Self, Self::Error> {
326 StrictFinitePolicy::<f64, 53>::validate(self)
327 .map_err(|e| TanRealInputErrors::InvalidArgument { source: e }.into())
328 .and_then(|v| {
329 if v.cos() == 0. {
336 Err(TanRealInputErrors::ArgumentIsPole {
337 value: v,
338 backtrace: capture_backtrace(),
339 }
340 .into())
341 } else {
342 StrictFinitePolicy::<f64, 53>::validate(f64::tan(v))
343 .map_err(|e| TanRealErrors::Output { source: e })
344 }
345 })
346 }
347
348 #[inline(always)]
349 fn tan(self) -> Self {
350 #[cfg(debug_assertions)]
351 {
352 self.try_tan().unwrap()
353 }
354 #[cfg(not(debug_assertions))]
355 {
356 f64::tan(self)
357 }
358 }
359}
360
361#[duplicate_item(
362 T E ErrIn try_func func;
363 [ASin] [ASinRealErrors] [ASinRealInputErrors] [try_asin] [asin];
364 [ACos] [ACosRealErrors] [ACosRealInputErrors] [try_acos] [acos];
365)]
366impl T for f64 {
367 type Error = E<f64>;
368
369 #[inline(always)]
370 fn try_func(self) -> Result<Self, <Self as T>::Error> {
371 StrictFinitePolicy::<f64, 53>::validate(self)
372 .map_err(|e| ErrIn::InvalidArgument { source: e }.into())
373 .and_then(|v| {
374 if !(-1.0..=1.0).contains(&v) {
375 Err(ErrIn::OutOfDomain {
376 value: v,
377 backtrace: capture_backtrace(),
378 }
379 .into())
380 } else {
381 StrictFinitePolicy::<f64, 53>::validate(f64::func(v))
382 .map_err(|e| E::Output { source: e })
383 }
384 })
385 }
386
387 #[inline(always)]
388 fn func(self) -> Self {
389 #[cfg(debug_assertions)]
390 {
391 self.try_func().unwrap()
392 }
393 #[cfg(not(debug_assertions))]
394 {
395 f64::func(self)
396 }
397 }
398}
399
400impl ATan for Complex<f64> {
401 type Error = ATanComplexErrors<Complex<f64>>;
402
403 #[inline(always)]
404 fn try_atan(self) -> Result<Self, <Self as ATan>::Error> {
405 if self.re == 0. && self.im.abs() == 1. {
406 Err(ATanComplexInputErrors::ArgumentIsPole {
407 value: self,
408 backtrace: capture_backtrace(),
409 }
410 .into())
411 } else {
412 StrictFinitePolicy::<Complex<f64>, 53>::validate(self)
413 .map_err(|e| ATanComplexInputErrors::InvalidArgument { source: e }.into())
414 .and_then(|v| {
415 StrictFinitePolicy::<Complex<f64>, 53>::validate(Complex::<f64>::atan(v))
416 .map_err(|e| Self::Error::Output { source: e })
417 })
418 }
419 }
420
421 #[inline(always)]
422 fn atan(self) -> Self {
423 #[cfg(debug_assertions)]
424 {
425 self.try_atan().unwrap()
426 }
427 #[cfg(not(debug_assertions))]
428 {
429 Complex::<f64>::atan(self)
430 }
431 }
432}
433
434#[derive(Debug, Error)]
448pub enum ATan2InputErrors<RawReal: RawRealTrait> {
449 #[error("the numerator is invalid!")]
455 InvalidNumerator {
456 #[source]
458 #[backtrace]
459 source: <RawReal as RawScalarTrait>::ValidationErrors,
460 },
461
462 #[error("the denominator is invalid!")]
468 InvalidDenominator {
469 #[source]
471 #[backtrace]
472 source: <RawReal as RawScalarTrait>::ValidationErrors,
473 },
474
475 #[error("the numerator and the denominator are both zero!")]
480 ZeroOverZero {
481 backtrace: Backtrace,
483 },
484}
485
486pub type ATan2Errors<RawReal> =
518 FunctionErrors<ATan2InputErrors<RawReal>, <RawReal as RawScalarTrait>::ValidationErrors>;
519
520pub trait ATan2: Sized {
581 type Error: std::error::Error;
583
584 #[must_use = "this `Result` may contain an error that should be handled"]
606 fn try_atan2(self, denominator: &Self) -> Result<Self, Self::Error>;
607
608 fn atan2(self, denominator: &Self) -> Self;
611}
612
613impl ATan2 for f64 {
614 type Error = ATan2Errors<f64>;
616
617 fn try_atan2(self, denominator: &Self) -> Result<Self, Self::Error> {
646 let denominator = StrictFinitePolicy::<f64, 53>::validate(*denominator)
648 .map_err(|e| ATan2InputErrors::InvalidDenominator { source: e })?;
649
650 let numerator = StrictFinitePolicy::<f64, 53>::validate(self)
652 .map_err(|e| ATan2InputErrors::InvalidNumerator { source: e })?;
653
654 if numerator == 0.0 && denominator == 0.0 {
659 Err(ATan2InputErrors::ZeroOverZero {
660 backtrace: capture_backtrace(),
661 }
662 .into())
663 } else {
664 StrictFinitePolicy::<f64, 53>::validate(f64::atan2(self, denominator))
665 .map_err(|e| ATan2Errors::Output { source: e })
666 }
667 }
668
669 fn atan2(self, denominator: &Self) -> Self {
692 #[cfg(debug_assertions)]
693 {
694 self.try_atan2(denominator).unwrap()
695 }
696 #[cfg(not(debug_assertions))]
697 {
698 f64::atan2(self, *denominator)
699 }
700 }
701}
702pub trait TrigonometricFunctions: Sin + ASin + Cos + ACos + Tan + ATan {}
743
744#[duplicate_item(
745 T;
746 [f64];
747 [Complex<f64>];
748)]
749impl TrigonometricFunctions for T {}
750#[cfg(test)]
754mod tests {
755 use super::*;
756 use approx::assert_ulps_eq;
757 use num::Complex;
758
759 #[cfg(feature = "rug")]
760 use crate::backends::rug::validated::{ComplexRugStrictFinite, RealRugStrictFinite};
761
762 #[cfg(feature = "rug")]
763 use try_create::TryNew;
764
765 mod sin {
766 use super::*;
767
768 mod native64 {
769 use super::*;
770
771 mod real {
772 use super::*;
773
774 #[test]
775 fn sin_valid() {
776 let value = 4.0;
777 let expected_result = -0.7568024953079282;
778 assert_ulps_eq!(value.try_sin().unwrap(), expected_result);
779 assert_ulps_eq!(value.sin(), expected_result);
780 }
781
782 #[test]
783 fn sin_negative() {
784 let value = -4.0;
785 let expected_result = 0.7568024953079282;
786 assert_ulps_eq!(value.try_sin().unwrap(), expected_result);
787 assert_ulps_eq!(value.sin(), expected_result);
788 }
789
790 #[test]
791 fn sin_zero() {
792 let value = 0.0;
793 assert_eq!(value.try_sin().unwrap(), 0.0);
794 assert_eq!(value.sin(), 0.0);
795 }
796
797 #[test]
798 fn sin_nan() {
799 let value = f64::NAN;
800 let result = value.try_sin();
801 assert!(matches!(result, Err(SinErrors::Input { .. })));
802 }
803
804 #[test]
805 fn sin_infinity() {
806 let value = f64::INFINITY;
807 assert!(matches!(value.try_sin(), Err(SinErrors::Input { .. })));
808 }
809
810 #[test]
811 fn sin_subnormal() {
812 let value = f64::MIN_POSITIVE / 2.0;
813 assert!(matches!(value.try_sin(), Err(SinErrors::Input { .. })));
814 }
815 }
816
817 mod complex {
818 use super::*;
819
820 #[test]
821 fn sin_valid() {
822 let value = Complex::new(4.0, 1.0);
823 let expected_result = if cfg!(target_arch = "x86_64") {
824 Complex::new(-1.1678072748895183, -0.7681627634565731)
825 } else if cfg!(target_arch = "aarch64") {
826 Complex::new(-1.1678072748895185, -0.7681627634565731)
827 } else {
828 todo!("Architecture not-tested");
829 };
830
831 assert_eq!(value.try_sin().unwrap(), expected_result);
832 assert_eq!(<Complex<f64> as Sin>::sin(value), expected_result);
833 assert_eq!(value.sin(), expected_result);
834 }
835
836 #[test]
837 fn sin_zero() {
838 let value = Complex::new(0.0, 0.0);
839 let expected_result = Complex::new(0.0, 0.0);
840 assert_eq!(value.try_sin().unwrap(), expected_result);
841 assert_eq!(value.sin(), expected_result);
842 }
843
844 #[test]
845 fn sin_nan() {
846 let value = Complex::new(f64::NAN, 0.0);
847 assert!(matches!(value.try_sin(), Err(SinErrors::Input { .. })));
848
849 let value = Complex::new(0.0, f64::NAN);
850 assert!(matches!(value.try_sin(), Err(SinErrors::Input { .. })));
851 }
852
853 #[test]
854 fn sin_infinity() {
855 let value = Complex::new(f64::INFINITY, 0.0);
856 assert!(matches!(value.try_sin(), Err(SinErrors::Input { .. })));
857
858 let value = Complex::new(0.0, f64::INFINITY);
859 assert!(matches!(value.try_sin(), Err(SinErrors::Input { .. })));
860 }
861
862 #[test]
863 fn sin_subnormal() {
864 let value = Complex::new(f64::MIN_POSITIVE / 2.0, 0.0);
865 assert!(matches!(value.try_sin(), Err(SinErrors::Input { .. })));
866
867 let value = Complex::new(0.0, f64::MIN_POSITIVE / 2.0);
868 assert!(matches!(value.try_sin(), Err(SinErrors::Input { .. })));
869 }
870 }
871 }
872
873 #[cfg(feature = "rug")]
874 mod rug53 {
875 use super::*;
876
877 mod real {
878 use super::*;
879
880 #[test]
881 fn test_rug_float_sin_valid() {
882 let value =
883 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, -4.0)).unwrap();
884
885 let expected_result = RealRugStrictFinite::<53>::try_new(rug::Float::with_val(
886 53,
887 7.568024953079282e-1,
888 ))
889 .unwrap();
890 assert_eq!(value.clone().try_sin().unwrap(), expected_result);
891 assert_eq!(value.sin(), expected_result);
892 }
893
894 #[test]
895 fn test_rug_float_sin_zero() {
896 let value =
897 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.0)).unwrap();
898
899 let expected_result =
900 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.0)).unwrap();
901 assert_eq!(value.clone().try_sin().unwrap(), expected_result);
902 assert_eq!(value.sin(), expected_result);
903 }
904 }
905
906 mod complex {
907 use super::*;
908
909 #[test]
910 fn test_complex_rug_float_sin_valid() {
911 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
912 53,
913 (rug::Float::with_val(53, 4.0), rug::Float::with_val(53, 1.0)),
914 ))
915 .unwrap();
916
917 let expected_result =
918 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
919 53,
920 (
921 rug::Float::with_val(53, -1.1678072748895185),
922 rug::Float::with_val(53, -7.681627634565731e-1),
923 ),
924 ))
925 .unwrap();
926 assert_eq!(value.clone().try_sin().unwrap(), expected_result);
927 assert_eq!(value.sin(), expected_result);
928 }
929
930 #[test]
931 fn test_complex_rug_float_sin_zero() {
932 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
933 53,
934 (rug::Float::with_val(53, 0.0), rug::Float::with_val(53, 0.0)),
935 ))
936 .unwrap();
937
938 let expected_result =
939 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
940 53,
941 (rug::Float::with_val(53, 0.), rug::Float::with_val(53, 0.)),
942 ))
943 .unwrap();
944 assert_eq!(value.clone().try_sin().unwrap(), expected_result);
945 assert_eq!(value.sin(), expected_result);
946 }
947 }
948 }
949 }
950
951 mod cos {
952 use super::*;
953
954 mod native64 {
955 use super::*;
956
957 mod real {
958 use super::*;
959
960 #[test]
961 fn cos_valid() {
962 let value = 4.0;
963 let expected_result = -0.6536436208636119;
964 assert_eq!(value.try_cos().unwrap(), expected_result);
965 assert_eq!(value.cos(), expected_result);
966 }
967
968 #[test]
969 fn cos_negative() {
970 let value = -4.0;
971 let expected_result = -0.6536436208636119;
972 assert_eq!(value.try_cos().unwrap(), expected_result);
973 assert_eq!(value.cos(), expected_result);
974 }
975
976 #[test]
977 fn cos_zero() {
978 let value = 0.0;
979 assert_eq!(value.try_cos().unwrap(), 1.0);
980 assert_eq!(value.cos(), 1.0);
981 }
982
983 #[test]
984 fn cos_nan() {
985 let value = f64::NAN;
986 let result = value.try_cos();
987 assert!(matches!(result, Err(CosErrors::Input { .. })));
988 }
989
990 #[test]
991 fn cos_infinity() {
992 let value = f64::INFINITY;
993 assert!(matches!(value.try_cos(), Err(CosErrors::Input { .. })));
994 }
995
996 #[test]
997 fn cos_subnormal() {
998 let value = f64::MIN_POSITIVE / 2.0;
999 assert!(matches!(value.try_cos(), Err(CosErrors::Input { .. })));
1000 }
1001 }
1002
1003 mod complex {
1004 use super::*;
1005
1006 #[test]
1007 fn cos_valid() {
1008 let value = Complex::new(4.0, 1.0);
1009 let expected_result = if cfg!(target_arch = "x86_64") {
1010 Complex::new(-1.0086248134251568, 0.8893951958384846)
1011 } else if cfg!(target_arch = "aarch64") {
1012 Complex::new(-1.0086248134251568, 0.8893951958384847)
1013 } else {
1014 todo!("Architecture not-tested");
1015 };
1016 assert_eq!(value.try_cos().unwrap(), expected_result);
1017 assert_eq!(<Complex<f64> as Cos>::cos(value), expected_result);
1018 assert_eq!(value.cos(), expected_result);
1019 }
1020
1021 #[test]
1022 fn cos_zero() {
1023 let value = Complex::new(0.0, 0.0);
1024 let expected_result = Complex::new(1.0, 0.0);
1025 assert_eq!(value.try_cos().unwrap(), expected_result);
1026 assert_eq!(value.cos(), expected_result);
1027 }
1028
1029 #[test]
1030 fn cos_nan() {
1031 let value = Complex::new(f64::NAN, 0.0);
1032 assert!(matches!(value.try_cos(), Err(CosErrors::Input { .. })));
1033
1034 let value = Complex::new(0.0, f64::NAN);
1035 assert!(matches!(value.try_cos(), Err(CosErrors::Input { .. })));
1036 }
1037
1038 #[test]
1039 fn cos_infinity() {
1040 let value = Complex::new(f64::INFINITY, 0.0);
1041 assert!(matches!(value.try_cos(), Err(CosErrors::Input { .. })));
1042
1043 let value = Complex::new(0.0, f64::INFINITY);
1044 assert!(matches!(value.try_cos(), Err(CosErrors::Input { .. })));
1045 }
1046
1047 #[test]
1048 fn cos_subnormal() {
1049 let value = Complex::new(f64::MIN_POSITIVE / 2.0, 0.0);
1050 assert!(matches!(value.try_cos(), Err(CosErrors::Input { .. })));
1051
1052 let value = Complex::new(0.0, f64::MIN_POSITIVE / 2.0);
1053 assert!(matches!(value.try_cos(), Err(CosErrors::Input { .. })));
1054 }
1055 }
1056 }
1057
1058 #[cfg(feature = "rug")]
1059 mod rug53 {
1060 use super::*;
1061
1062 mod real {
1063 use super::*;
1064
1065 #[test]
1066 fn test_rug_float_cos_valid() {
1067 let value =
1068 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, -4.0)).unwrap();
1069
1070 let expected_result = RealRugStrictFinite::<53>::try_new(rug::Float::with_val(
1071 53,
1072 -0.6536436208636119,
1073 ))
1074 .unwrap();
1075 assert_eq!(value.clone().try_cos().unwrap(), expected_result);
1076 assert_eq!(value.cos(), expected_result);
1077 }
1078
1079 #[test]
1080 fn test_rug_float_cos_zero() {
1081 let value =
1082 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.0)).unwrap();
1083
1084 let expected_result =
1085 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 1.0)).unwrap();
1086 assert_eq!(value.clone().try_cos().unwrap(), expected_result);
1087 assert_eq!(value.cos(), expected_result);
1088 }
1089 }
1090
1091 mod complex {
1092 use super::*;
1093
1094 #[test]
1095 fn test_complex_rug_float_cos_valid() {
1096 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1097 53,
1098 (rug::Float::with_val(53, 4.0), rug::Float::with_val(53, 1.0)),
1099 ))
1100 .unwrap();
1101
1102 let expected_result =
1103 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1104 53,
1105 (
1106 rug::Float::with_val(53, -1.0086248134251568),
1107 rug::Float::with_val(53, 8.893951958384847e-1),
1108 ),
1109 ))
1110 .unwrap();
1111 assert_eq!(value.clone().try_cos().unwrap(), expected_result);
1112 assert_eq!(value.cos(), expected_result);
1113 }
1114
1115 #[test]
1116 fn test_complex_rug_float_cos_zero() {
1117 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1118 53,
1119 (rug::Float::with_val(53, 0.0), rug::Float::with_val(53, 0.0)),
1120 ))
1121 .unwrap();
1122
1123 let expected_result =
1124 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1125 53,
1126 (rug::Float::with_val(53, 1.), rug::Float::with_val(53, 0.)),
1127 ))
1128 .unwrap();
1129 assert_eq!(value.clone().try_cos().unwrap(), expected_result);
1130 assert_eq!(value.cos(), expected_result);
1131 }
1132 }
1133 }
1134 }
1135
1136 mod tan {
1137 use super::*;
1138
1139 mod native64 {
1140 use super::*;
1141
1142 mod real {
1143 use super::*;
1144
1145 #[test]
1146 fn tan_valid() {
1147 let value = 4.0;
1148 let expected_result = 1.1578212823495775;
1149 assert_eq!(value.try_tan().unwrap(), expected_result);
1150 assert_eq!(<f64 as Tan>::tan(value), expected_result);
1151 assert_eq!(value.tan(), expected_result);
1152 }
1153
1154 #[test]
1170 fn tan_negative() {
1171 let value = -4.0;
1172 let expected_result = -1.1578212823495775;
1173 assert_eq!(value.try_tan().unwrap(), expected_result);
1174 assert_eq!(value.tan(), expected_result);
1175 }
1176
1177 #[test]
1178 fn tan_zero() {
1179 let value = 0.0;
1180 assert_eq!(value.try_tan().unwrap(), 0.0);
1181 assert_eq!(value.tan(), 0.0);
1182 }
1183
1184 #[test]
1185 fn tan_nan() {
1186 let value = f64::NAN;
1187 let result = value.try_tan();
1188 assert!(matches!(result, Err(TanRealErrors::Input { .. })));
1189 }
1190
1191 #[test]
1192 fn tan_infinity() {
1193 let value = f64::INFINITY;
1194 assert!(matches!(value.try_tan(), Err(TanRealErrors::Input { .. })));
1195 }
1196
1197 #[test]
1198 fn tan_subnormal() {
1199 let value = f64::MIN_POSITIVE / 2.0;
1200 assert!(matches!(value.try_tan(), Err(TanRealErrors::Input { .. })));
1201 }
1202 }
1203
1204 mod complex {
1205 use super::*;
1206
1207 #[test]
1208 fn tan_valid() {
1209 let value = Complex::new(4.0, 1.0);
1210 let expected_result = Complex::new(0.27355308280730734, 1.002810507583505);
1211 assert_eq!(value.try_tan().unwrap(), expected_result);
1212 assert_eq!(<Complex<f64> as Tan>::tan(value), expected_result);
1213 assert_eq!(value.tan(), expected_result);
1214 }
1215
1216 #[test]
1217 fn tan_zero() {
1218 let value = Complex::new(0.0, 0.0);
1219 let expected_result = Complex::new(0.0, 0.0);
1220 assert_eq!(value.try_tan().unwrap(), expected_result);
1221 assert_eq!(value.tan(), expected_result);
1222 }
1223
1224 #[test]
1225 fn tan_nan() {
1226 let value = Complex::new(f64::NAN, 0.0);
1227 assert!(matches!(
1228 value.try_tan(),
1229 Err(TanComplexErrors::Input { .. })
1230 ));
1231
1232 let value = Complex::new(0.0, f64::NAN);
1233 assert!(matches!(
1234 value.try_tan(),
1235 Err(TanComplexErrors::Input { .. })
1236 ));
1237 }
1238
1239 #[test]
1240 fn tan_infinity() {
1241 let value = Complex::new(f64::INFINITY, 0.0);
1242 assert!(matches!(
1243 value.try_tan(),
1244 Err(TanComplexErrors::Input { .. })
1245 ));
1246
1247 let value = Complex::new(0.0, f64::INFINITY);
1248 assert!(matches!(
1249 value.try_tan(),
1250 Err(TanComplexErrors::Input { .. })
1251 ));
1252 }
1253
1254 #[test]
1255 fn tan_subnormal() {
1256 let value = Complex::new(f64::MIN_POSITIVE / 2.0, 0.0);
1257 assert!(matches!(
1258 value.try_tan(),
1259 Err(TanComplexErrors::Input { .. })
1260 ));
1261
1262 let value = Complex::new(0.0, f64::MIN_POSITIVE / 2.0);
1263 assert!(matches!(
1264 value.try_tan(),
1265 Err(TanComplexErrors::Input { .. })
1266 ));
1267 }
1268 }
1269 }
1270
1271 #[cfg(feature = "rug")]
1272 mod rug53 {
1273 use super::*;
1274
1275 mod real {
1276 use super::*;
1277
1278 #[test]
1279 fn test_rug_float_tan_valid() {
1280 let value =
1281 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, -4.0)).unwrap();
1282
1283 let expected_result = RealRugStrictFinite::<53>::try_new(rug::Float::with_val(
1284 53,
1285 -1.1578212823495775,
1286 ))
1287 .unwrap();
1288 assert_eq!(value.clone().try_tan().unwrap(), expected_result);
1289 assert_eq!(value.tan(), expected_result);
1290 }
1291
1292 #[cfg(feature = "rug")]
1293 #[test]
1294 fn test_rug_float_tan_zero() {
1295 let value =
1296 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.0)).unwrap();
1297
1298 let expected_result =
1299 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.0)).unwrap();
1300 assert_eq!(value.clone().try_tan().unwrap(), expected_result);
1301 assert_eq!(value.tan(), expected_result);
1302 }
1303
1304 }
1329
1330 mod complex {
1331 use super::*;
1332
1333 #[test]
1334 fn test_complex_rug_float_tan_valid() {
1335 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1336 53,
1337 (rug::Float::with_val(53, 4.0), rug::Float::with_val(53, 1.0)),
1338 ))
1339 .unwrap();
1340
1341 let expected_result =
1342 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1343 53,
1344 (
1345 rug::Float::with_val(53, 2.7355308280730734e-1),
1346 rug::Float::with_val(53, 1.002810507583505),
1347 ),
1348 ))
1349 .unwrap();
1350 assert_eq!(value.clone().try_tan().unwrap(), expected_result);
1351 assert_eq!(value.tan(), expected_result);
1352 }
1353
1354 #[test]
1355 fn test_complex_rug_float_tan_zero() {
1356 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1357 53,
1358 (rug::Float::with_val(53, 0.0), rug::Float::with_val(53, 0.0)),
1359 ))
1360 .unwrap();
1361
1362 let expected_result =
1363 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1364 53,
1365 (rug::Float::with_val(53, 0.), rug::Float::with_val(53, 0.)),
1366 ))
1367 .unwrap();
1368 assert_eq!(value.clone().try_tan().unwrap(), expected_result);
1369 assert_eq!(value.tan(), expected_result);
1370 }
1371
1372 }
1407 }
1408 }
1409
1410 mod atan {
1411 use super::*;
1412
1413 mod native64 {
1414 use super::*;
1415
1416 mod real {
1417 use super::*;
1418
1419 #[test]
1420 fn atan_valid() {
1421 let value = 4.0;
1422 let expected_result = 1.3258176636680326;
1423 assert_eq!(value.try_atan().unwrap(), expected_result);
1424 assert_eq!(value.atan(), expected_result);
1425 }
1426
1427 #[test]
1428 fn atan_negative() {
1429 let value = -4.0;
1430 let expected_result = -1.3258176636680326;
1431 assert_eq!(value.try_atan().unwrap(), expected_result);
1432 assert_eq!(value.atan(), expected_result);
1433 }
1434
1435 #[test]
1436 fn atan_zero() {
1437 let value = 0.0;
1438 assert_eq!(value.try_atan().unwrap(), 0.0);
1439 assert_eq!(value.atan(), 0.0);
1440 }
1441
1442 #[test]
1443 fn atan_nan() {
1444 let value = f64::NAN;
1445 let result = value.try_atan();
1446 assert!(matches!(result, Err(ATanRealErrors::Input { .. })));
1447 }
1448
1449 #[test]
1450 fn atan_infinity() {
1451 let value = f64::INFINITY;
1452 assert!(matches!(
1453 value.try_atan(),
1454 Err(ATanRealErrors::Input { .. })
1455 ));
1456 }
1457
1458 #[test]
1459 fn atan_subnormal() {
1460 let value = f64::MIN_POSITIVE / 2.0;
1461 assert!(matches!(
1462 value.try_atan(),
1463 Err(ATanRealErrors::Input { .. })
1464 ));
1465 }
1466 }
1467
1468 mod complex {
1469 use super::*;
1470
1471 #[test]
1472 fn atan_valid() {
1473 let value = Complex::new(4.0, 1.0);
1474 let expected_result = Complex::new(1.3389725222944935, 0.05578588782855254);
1475 assert_eq!(value.try_atan().unwrap(), expected_result);
1476 assert_eq!(<Complex<f64> as ATan>::atan(value), expected_result);
1477 assert_eq!(value.atan(), expected_result);
1478 }
1479
1480 #[test]
1481 fn atan_out_of_domain() {
1482 let value = Complex::new(0.0, 1.0);
1483 let err = value.try_atan().unwrap_err();
1484 assert!(matches!(
1485 err,
1486 ATanComplexErrors::Input {
1487 source: ATanComplexInputErrors::ArgumentIsPole { .. }
1488 }
1489 ));
1490
1491 let value = Complex::new(0.0, -1.0);
1492 let err = value.try_atan().unwrap_err();
1493 assert!(matches!(
1494 err,
1495 ATanComplexErrors::Input {
1496 source: ATanComplexInputErrors::ArgumentIsPole { .. }
1497 }
1498 ));
1499 }
1500
1501 #[test]
1502 fn atan_zero() {
1503 let value = Complex::new(0.0, 0.0);
1504 let expected_result = Complex::new(0.0, 0.0);
1505 assert_eq!(value.try_atan().unwrap(), expected_result);
1506 assert_eq!(value.atan(), expected_result);
1507 }
1508
1509 #[test]
1510 fn atan_nan() {
1511 let value = Complex::new(f64::NAN, 0.0);
1512 assert!(matches!(
1513 value.try_atan(),
1514 Err(ATanComplexErrors::Input { .. })
1515 ));
1516
1517 let value = Complex::new(0.0, f64::NAN);
1518 assert!(matches!(
1519 value.try_atan(),
1520 Err(ATanComplexErrors::Input { .. })
1521 ));
1522 }
1523
1524 #[test]
1525 fn atan_infinity() {
1526 let value = Complex::new(f64::INFINITY, 0.0);
1527 assert!(matches!(
1528 value.try_atan(),
1529 Err(ATanComplexErrors::Input { .. })
1530 ));
1531
1532 let value = Complex::new(0.0, f64::INFINITY);
1533 assert!(matches!(
1534 value.try_atan(),
1535 Err(ATanComplexErrors::Input { .. })
1536 ));
1537 }
1538
1539 #[test]
1540 fn atan_subnormal() {
1541 let value = Complex::new(f64::MIN_POSITIVE / 2.0, 0.0);
1542 assert!(matches!(
1543 value.try_atan(),
1544 Err(ATanComplexErrors::Input { .. })
1545 ));
1546
1547 let value = Complex::new(0.0, f64::MIN_POSITIVE / 2.0);
1548 assert!(matches!(
1549 value.try_atan(),
1550 Err(ATanComplexErrors::Input { .. })
1551 ));
1552 }
1553 }
1554 }
1555
1556 #[cfg(feature = "rug")]
1557 mod rug53 {
1558 use super::*;
1559
1560 mod real {
1561 use super::*;
1562
1563 #[test]
1564 fn test_rug_float_atan_valid() {
1565 let value =
1566 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, -4.0)).unwrap();
1567
1568 let expected_result = RealRugStrictFinite::<53>::try_new(rug::Float::with_val(
1569 53,
1570 -1.3258176636680326,
1571 ))
1572 .unwrap();
1573 assert_eq!(value.clone().try_atan().unwrap(), expected_result);
1574 assert_eq!(value.atan(), expected_result);
1575 }
1576
1577 #[test]
1578 fn test_rug_float_atan_zero() {
1579 let value =
1580 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.0)).unwrap();
1581
1582 let expected_result =
1583 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.0)).unwrap();
1584 assert_eq!(value.clone().try_atan().unwrap(), expected_result);
1585 assert_eq!(value.atan(), expected_result);
1586 }
1587 }
1588
1589 mod complex {
1590 use super::*;
1591
1592 #[test]
1593 fn test_complex_rug_float_atan_valid() {
1594 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1595 53,
1596 (rug::Float::with_val(53, 4.0), rug::Float::with_val(53, 1.0)),
1597 ))
1598 .unwrap();
1599
1600 let expected_result =
1601 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1602 53,
1603 (
1604 rug::Float::with_val(53, 1.3389725222944935),
1605 rug::Float::with_val(53, 5.578588782855244e-2),
1606 ),
1607 ))
1608 .unwrap();
1609 assert_eq!(value.clone().try_atan().unwrap(), expected_result);
1610 assert_eq!(value.atan(), expected_result);
1611 }
1612
1613 #[test]
1614 fn test_complex_rug_float_atan_zero() {
1615 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1616 53,
1617 (rug::Float::with_val(53, 0.0), rug::Float::with_val(53, 0.0)),
1618 ))
1619 .unwrap();
1620
1621 let expected_result =
1622 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1623 53,
1624 (rug::Float::with_val(53, 0.), rug::Float::with_val(53, 0.)),
1625 ))
1626 .unwrap();
1627 assert_eq!(value.clone().try_atan().unwrap(), expected_result);
1628 assert_eq!(value.atan(), expected_result);
1629 }
1630 }
1631 }
1632 }
1633
1634 mod asin {
1635 use super::*;
1636
1637 mod native64 {
1638 use super::*;
1639
1640 mod real {
1641 use super::*;
1642
1643 #[test]
1644 fn asin_valid() {
1645 let value = 0.5;
1646 let expected_result = std::f64::consts::FRAC_PI_6;
1647
1648 assert_ulps_eq!(value.try_asin().unwrap(), expected_result);
1649 assert_ulps_eq!(value.asin(), expected_result);
1650 }
1651
1652 #[test]
1653 fn asin_negative() {
1654 let value = -0.5;
1655 let expected_result = -std::f64::consts::FRAC_PI_6;
1656
1657 assert_ulps_eq!(value.try_asin().unwrap(), expected_result);
1658 assert_ulps_eq!(value.asin(), expected_result);
1659 }
1660
1661 #[test]
1662 fn asin_zero() {
1663 let value = 0.0;
1664 assert_eq!(value.try_asin().unwrap(), 0.0);
1665 assert_eq!(value.asin(), 0.0);
1666 }
1667
1668 #[test]
1669 fn test_rug_float_asin_out_of_bound() {
1670 let value = 2.0;
1671 let result = value.try_asin();
1672 println!("result: {result:?}");
1673 assert!(matches!(result, Err(ASinRealErrors::Input { .. })));
1674 }
1675
1676 #[test]
1677 fn asin_nan() {
1678 let value = f64::NAN;
1679 let result = value.try_asin();
1680 assert!(matches!(result, Err(ASinRealErrors::Input { .. })));
1681 }
1682
1683 #[test]
1684 fn asin_infinity() {
1685 let value = f64::INFINITY;
1686 assert!(matches!(
1687 value.try_asin(),
1688 Err(ASinRealErrors::Input { .. })
1689 ));
1690 }
1691
1692 #[test]
1693 fn asin_subnormal() {
1694 let value = f64::MIN_POSITIVE / 2.0;
1695 assert!(matches!(
1696 value.try_asin(),
1697 Err(ASinRealErrors::Input { .. })
1698 ));
1699 }
1700 }
1701
1702 mod complex {
1703 use super::*;
1704
1705 #[test]
1706 fn asin_valid() {
1707 let value = Complex::new(0.5, 0.5);
1708 let expected_result = Complex::new(0.4522784471511907, 0.5306375309525178);
1709 assert_eq!(value.try_asin().unwrap(), expected_result);
1710 assert_eq!(<Complex<f64> as ASin>::asin(value), expected_result);
1711 assert_eq!(value.asin(), expected_result);
1712 }
1713
1714 #[test]
1715 fn asin_zero() {
1716 let value = Complex::new(0.0, 0.0);
1717 let expected_result = Complex::new(0.0, 0.0);
1718 assert_eq!(value.try_asin().unwrap(), expected_result);
1719 assert_eq!(value.asin(), expected_result);
1720 }
1721
1722 #[test]
1723 fn asin_nan() {
1724 let value = Complex::new(f64::NAN, 0.0);
1725 assert!(matches!(
1726 value.try_asin(),
1727 Err(ASinComplexErrors::Input { .. })
1728 ));
1729
1730 let value = Complex::new(0.0, f64::NAN);
1731 assert!(matches!(
1732 value.try_asin(),
1733 Err(ASinComplexErrors::Input { .. })
1734 ));
1735 }
1736
1737 #[test]
1738 fn asin_infinity() {
1739 let value = Complex::new(f64::INFINITY, 0.0);
1740 assert!(matches!(
1741 value.try_asin(),
1742 Err(ASinComplexErrors::Input { .. })
1743 ));
1744
1745 let value = Complex::new(0.0, f64::INFINITY);
1746 assert!(matches!(
1747 value.try_asin(),
1748 Err(ASinComplexErrors::Input { .. })
1749 ));
1750 }
1751
1752 #[test]
1753 fn asin_subnormal() {
1754 let value = Complex::new(f64::MIN_POSITIVE / 2.0, 0.0);
1755 assert!(matches!(
1756 value.try_asin(),
1757 Err(ASinComplexErrors::Input { .. })
1758 ));
1759
1760 let value = Complex::new(0.0, f64::MIN_POSITIVE / 2.0);
1761 assert!(matches!(
1762 value.try_asin(),
1763 Err(ASinComplexErrors::Input { .. })
1764 ));
1765 }
1766 }
1767 }
1768
1769 #[cfg(feature = "rug")]
1770 mod rug53 {
1771 use super::*;
1772
1773 mod real {
1774 use super::*;
1775
1776 #[test]
1777 fn test_rug_float_asin_valid() {
1778 let value =
1779 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.5)).unwrap();
1780
1781 let expected_result = RealRugStrictFinite::<53>::try_new(rug::Float::with_val(
1782 53,
1783 std::f64::consts::FRAC_PI_6,
1784 ))
1785 .unwrap();
1786 assert_eq!(value.clone().try_asin().unwrap(), expected_result);
1787 assert_eq!(value.asin(), expected_result);
1788 }
1789
1790 #[test]
1791 fn test_rug_float_asin_zero() {
1792 let value =
1793 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.0)).unwrap();
1794
1795 let expected_result =
1796 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.0)).unwrap();
1797 assert_eq!(value.clone().try_asin().unwrap(), expected_result);
1798 assert_eq!(value.asin(), expected_result);
1799 }
1800
1801 #[test]
1802 fn test_rug_float_asin_out_of_bound() {
1803 let value =
1804 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 2.0)).unwrap();
1805 let result = value.try_asin();
1806 println!("result: {result:?}");
1807 assert!(matches!(result, Err(ASinRealErrors::Input { .. })));
1808 }
1809 }
1810
1811 mod complex {
1812 use super::*;
1813
1814 #[test]
1815 fn test_complex_rug_float_asin_valid() {
1816 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1817 53,
1818 (rug::Float::with_val(53, 0.5), rug::Float::with_val(53, 0.5)),
1819 ))
1820 .unwrap();
1821
1822 let expected_result =
1823 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1824 53,
1825 (
1826 rug::Float::with_val(53, 0.4522784471511907),
1827 rug::Float::with_val(53, 0.5306375309525179),
1828 ),
1829 ))
1830 .unwrap();
1831 assert_eq!(value.clone().try_asin().unwrap(), expected_result);
1832 assert_eq!(value.asin(), expected_result);
1833 }
1834
1835 #[test]
1836 fn test_complex_rug_float_asin_zero() {
1837 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1838 53,
1839 (rug::Float::with_val(53, 0.0), rug::Float::with_val(53, 0.0)),
1840 ))
1841 .unwrap();
1842
1843 let expected_result =
1844 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1845 53,
1846 (rug::Float::with_val(53, 0.), rug::Float::with_val(53, 0.)),
1847 ))
1848 .unwrap();
1849 assert_eq!(value.clone().try_asin().unwrap(), expected_result);
1850 assert_eq!(value.asin(), expected_result);
1851 }
1852 }
1853 }
1854 }
1855
1856 mod acos {
1857 use super::*;
1858
1859 mod native64 {
1860 use super::*;
1861
1862 mod real {
1863 use super::*;
1864
1865 #[test]
1866 fn acos_valid() {
1867 let value = 0.5;
1868 let expected_result = std::f64::consts::FRAC_PI_3;
1869
1870 assert_ulps_eq!(value.try_acos().unwrap(), expected_result);
1871 assert_ulps_eq!(value.acos(), expected_result);
1872 }
1873
1874 #[test]
1875 fn acos_negative() {
1876 let value = -0.5;
1877 let expected_result = 2.0943951023931957;
1878 assert_eq!(value.try_acos().unwrap(), expected_result);
1879 assert_eq!(value.acos(), expected_result);
1880 }
1881
1882 #[test]
1883 fn acos_zero() {
1884 let value = 0.0;
1885 let expected_result = std::f64::consts::FRAC_PI_2;
1886 assert_eq!(value.try_acos().unwrap(), expected_result);
1887 assert_eq!(value.acos(), expected_result);
1888 }
1889
1890 #[test]
1891 fn test_rug_float_acos_out_of_bound() {
1892 let value = 2.0;
1893 let result = value.try_acos();
1894 println!("result: {result:?}");
1895 assert!(matches!(result, Err(ACosRealErrors::Input { .. })));
1896 }
1897
1898 #[test]
1899 fn acos_nan() {
1900 let value = f64::NAN;
1901 let result = value.try_acos();
1902 assert!(matches!(result, Err(ACosRealErrors::Input { .. })));
1903 }
1904
1905 #[test]
1906 fn acos_infinity() {
1907 let value = f64::INFINITY;
1908 assert!(matches!(
1909 value.try_acos(),
1910 Err(ACosRealErrors::Input { .. })
1911 ));
1912 }
1913
1914 #[test]
1915 fn acos_subnormal() {
1916 let value = f64::MIN_POSITIVE / 2.0;
1917 assert!(matches!(
1918 value.try_acos(),
1919 Err(ACosRealErrors::Input { .. })
1920 ));
1921 }
1922 }
1923
1924 mod complex {
1925 use super::*;
1926
1927 #[test]
1928 fn acos_valid() {
1929 let value = Complex::new(0.5, 0.5);
1930 let expected_result = Complex::new(1.118517879643706, -0.5306375309525179);
1931 assert_eq!(value.try_acos().unwrap(), expected_result);
1932 assert_eq!(<Complex<f64> as ACos>::acos(value), expected_result);
1933 assert_eq!(value.acos(), expected_result);
1934 }
1935
1936 #[test]
1937 fn acos_zero() {
1938 let value = Complex::new(0.0, 0.0);
1939 let expected_result = Complex::new(std::f64::consts::FRAC_PI_2, 0.0);
1940 assert_eq!(value.try_acos().unwrap(), expected_result);
1941 assert_eq!(value.acos(), expected_result);
1942 }
1943
1944 #[test]
1945 fn acos_nan() {
1946 let value = Complex::new(f64::NAN, 0.0);
1947 assert!(matches!(
1948 value.try_acos(),
1949 Err(ACosComplexErrors::Input { .. })
1950 ));
1951
1952 let value = Complex::new(0.0, f64::NAN);
1953 assert!(matches!(
1954 value.try_acos(),
1955 Err(ACosComplexErrors::Input { .. })
1956 ));
1957 }
1958
1959 #[test]
1960 fn acos_infinity() {
1961 let value = Complex::new(f64::INFINITY, 0.0);
1962 assert!(matches!(
1963 value.try_acos(),
1964 Err(ACosComplexErrors::Input { .. })
1965 ));
1966
1967 let value = Complex::new(0.0, f64::INFINITY);
1968 assert!(matches!(
1969 value.try_acos(),
1970 Err(ACosComplexErrors::Input { .. })
1971 ));
1972 }
1973
1974 #[test]
1975 fn acos_subnormal() {
1976 let value = Complex::new(f64::MIN_POSITIVE / 2.0, 0.0);
1977 assert!(matches!(
1978 value.try_acos(),
1979 Err(ACosComplexErrors::Input { .. })
1980 ));
1981
1982 let value = Complex::new(0.0, f64::MIN_POSITIVE / 2.0);
1983 assert!(matches!(
1984 value.try_acos(),
1985 Err(ACosComplexErrors::Input { .. })
1986 ));
1987 }
1988 }
1989 }
1990
1991 #[cfg(feature = "rug")]
1992 mod rug53 {
1993 use super::*;
1994
1995 mod real {
1996 use super::*;
1997
1998 #[test]
1999 fn test_rug_float_acos_valid() {
2000 let value =
2001 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.5)).unwrap();
2002
2003 let expected_result = RealRugStrictFinite::<53>::try_new(rug::Float::with_val(
2004 53,
2005 std::f64::consts::FRAC_PI_3,
2006 ))
2007 .unwrap();
2008 assert_eq!(value.clone().try_acos().unwrap(), expected_result);
2009 assert_eq!(value.acos(), expected_result);
2010 }
2011
2012 #[test]
2013 fn test_rug_float_acos_zero() {
2014 let value =
2015 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.0)).unwrap();
2016
2017 let expected_result = RealRugStrictFinite::<53>::try_new(rug::Float::with_val(
2018 53,
2019 std::f64::consts::FRAC_PI_2,
2020 ))
2021 .unwrap();
2022 assert_eq!(value.clone().try_acos().unwrap(), expected_result);
2023 assert_eq!(value.acos(), expected_result);
2024 }
2025
2026 #[test]
2027 fn test_rug_float_acos_out_of_bound() {
2028 let value =
2029 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 2.0)).unwrap();
2030 let result = value.try_acos();
2031 println!("result: {result:?}");
2032 assert!(matches!(result, Err(ACosRealErrors::Input { .. })));
2033 }
2034 }
2035
2036 mod complex {
2037 use super::*;
2038
2039 #[test]
2040 fn test_complex_rug_float_acos_valid() {
2041 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
2042 53,
2043 (rug::Float::with_val(53, 0.5), rug::Float::with_val(53, 0.5)),
2044 ))
2045 .unwrap();
2046
2047 let expected_result =
2048 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
2049 53,
2050 (
2051 rug::Float::with_val(53, 1.1185178796437059),
2052 rug::Float::with_val(53, -5.306375309525179e-1),
2053 ),
2054 ))
2055 .unwrap();
2056 assert_eq!(value.clone().try_acos().unwrap(), expected_result);
2057 assert_eq!(value.acos(), expected_result);
2058 }
2059
2060 #[test]
2061 fn test_complex_rug_float_acos_zero() {
2062 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
2063 53,
2064 (rug::Float::with_val(53, 0.0), rug::Float::with_val(53, 0.0)),
2065 ))
2066 .unwrap();
2067
2068 let expected_result =
2069 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
2070 53,
2071 (
2072 rug::Float::with_val(53, std::f64::consts::FRAC_PI_2),
2073 rug::Float::with_val(53, 0.),
2074 ),
2075 ))
2076 .unwrap();
2077 assert_eq!(value.clone().try_acos().unwrap(), expected_result);
2078 assert_eq!(value.acos(), expected_result);
2079 }
2080 }
2081 }
2082 }
2083
2084 mod atan2 {
2085 use super::*;
2086
2087 mod native64 {
2088 use super::*;
2089
2090 #[test]
2091 fn atan2_valid() {
2092 let numerator = 1.0;
2093 let denominator = 1.0;
2094 let expected_result = std::f64::consts::FRAC_PI_4; assert_eq!(numerator.atan2(&denominator), expected_result);
2096 assert_eq!(numerator.try_atan2(&denominator).unwrap(), expected_result);
2097 }
2098
2099 #[test]
2100 fn atan2_zero_numerator() {
2101 let numerator = 0.0;
2102 let denominator = 1.0;
2103 let expected_result = 0.0;
2104 assert_eq!(numerator.atan2(&denominator), expected_result);
2105 assert_eq!(numerator.try_atan2(&denominator).unwrap(), expected_result);
2106 }
2107
2108 #[test]
2109 fn atan2_zero_denominator() {
2110 let numerator = 1.0;
2111 let denominator = 0.0;
2112 let expected_result = std::f64::consts::FRAC_PI_2; assert_eq!(numerator.atan2(&denominator), expected_result);
2114 assert_eq!(numerator.try_atan2(&denominator).unwrap(), expected_result);
2115 }
2116
2117 #[test]
2118 fn atan2_zero_over_zero() {
2119 let numerator = 0.0;
2120 let denominator = 0.0;
2121 let result = numerator.try_atan2(&denominator);
2122 assert!(matches!(
2123 result,
2124 Err(ATan2Errors::Input {
2125 source: ATan2InputErrors::ZeroOverZero { .. }
2126 })
2127 ));
2128 }
2129
2130 #[test]
2131 fn atan2_negative_numerator() {
2132 let numerator = -1.0;
2133 let denominator = 1.0;
2134 let expected_result = -std::f64::consts::FRAC_PI_4; assert_eq!(numerator.atan2(&denominator), expected_result);
2136 assert_eq!(numerator.try_atan2(&denominator).unwrap(), expected_result);
2137 }
2138
2139 #[test]
2140 fn atan2_negative_denominator() {
2141 let numerator = 1.0;
2142 let denominator = -1.0;
2143 let expected_result = 2.356194490192345; assert_eq!(numerator.atan2(&denominator), expected_result);
2145 assert_eq!(numerator.try_atan2(&denominator).unwrap(), expected_result);
2146 }
2147
2148 #[test]
2149 fn atan2_nan_numerator() {
2150 let numerator = f64::NAN;
2151 let denominator = 1.0;
2152 let result = numerator.try_atan2(&denominator);
2153 assert!(result.is_err());
2154 }
2155
2156 #[test]
2157 fn atan2_nan_denominator() {
2158 let numerator = 1.0;
2159 let denominator = f64::NAN;
2160 let result = numerator.try_atan2(&denominator);
2161 assert!(result.is_err());
2162 }
2163 }
2164
2165 #[cfg(feature = "rug")]
2166 mod rug53 {
2167 use super::*;
2168 use rug::Float;
2169
2170 #[test]
2171 fn test_realrug_atan2_valid() {
2172 let numerator =
2173 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 1.0)).unwrap();
2174 let denominator =
2175 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 1.0)).unwrap();
2176 let expected_result = RealRugStrictFinite::<53>::try_new(Float::with_val(
2177 53,
2178 std::f64::consts::FRAC_PI_4,
2179 ))
2180 .unwrap(); assert_eq!(numerator.clone().atan2(&denominator), expected_result);
2182 assert_eq!(numerator.try_atan2(&denominator).unwrap(), expected_result);
2183 }
2184
2185 #[test]
2186 fn test_realrug_atan2_zero_numerator() {
2187 let numerator =
2188 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
2189 let denominator =
2190 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 1.0)).unwrap();
2191 let expected_result =
2192 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
2193 assert_eq!(numerator.clone().atan2(&denominator), expected_result);
2194 assert_eq!(numerator.try_atan2(&denominator).unwrap(), expected_result);
2195 }
2196
2197 #[test]
2198 fn test_realrug_atan2_zero_denominator() {
2199 let numerator =
2200 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 1.0)).unwrap();
2201 let denominator =
2202 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
2203 let expected_result = RealRugStrictFinite::<53>::try_new(Float::with_val(
2204 53,
2205 std::f64::consts::FRAC_PI_2,
2206 ))
2207 .unwrap(); assert_eq!(numerator.clone().atan2(&denominator), expected_result);
2209 assert_eq!(numerator.try_atan2(&denominator).unwrap(), expected_result);
2210 }
2211
2212 #[test]
2213 fn test_realrug_atan2_zero_over_zero() {
2214 let numerator =
2215 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
2216 let denominator =
2217 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
2218 let result = numerator.try_atan2(&denominator);
2219 assert!(matches!(
2220 result,
2221 Err(ATan2Errors::Input {
2222 source: ATan2InputErrors::ZeroOverZero { .. }
2223 })
2224 ));
2225 }
2226
2227 #[test]
2228 fn test_realrug_atan2_negative_numerator() {
2229 let numerator =
2230 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -1.0)).unwrap();
2231 let denominator =
2232 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 1.0)).unwrap();
2233 let expected_result = RealRugStrictFinite::<53>::try_new(Float::with_val(
2234 53,
2235 -std::f64::consts::FRAC_PI_4,
2236 ))
2237 .unwrap(); assert_eq!(numerator.clone().atan2(&denominator), expected_result);
2239 assert_eq!(numerator.try_atan2(&denominator).unwrap(), expected_result);
2240 }
2241
2242 #[test]
2243 fn test_realrug_atan2_negative_denominator() {
2244 let numerator =
2245 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 1.0)).unwrap();
2246 let denominator =
2247 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -1.0)).unwrap();
2248 let expected_result =
2249 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 2.356194490192345))
2250 .unwrap(); assert_eq!(numerator.clone().atan2(&denominator), expected_result);
2252 assert_eq!(numerator.try_atan2(&denominator).unwrap(), expected_result);
2253 }
2254 }
2255 }
2256}
2257