1#![deny(rustdoc::broken_intra_doc_links)]
2
3use crate::{
22 core::traits::{raw::RawScalarValidate, validation::sealed::NativeReal},
23 functions::FunctionErrors,
24 kernels::{RawComplexTrait, RawRealTrait, RawScalarTrait},
25};
26use duplicate::duplicate_item;
27use num::Complex;
28use num_traits::Float;
29use std::backtrace::Backtrace;
30use thiserror::Error;
31
32#[cfg(debug_assertions)]
33use crate::{Constants, core::errors::capture_backtrace};
34
35#[cfg(debug_assertions)]
36use num::Zero;
37
38#[duplicate_item(
42 enum_name enum_doc;
43 [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::ValidationError` (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."];
44 [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::ValidationError` (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."];
45)]
46#[derive(Debug, Error)]
47#[doc = enum_doc]
48pub enum enum_name<RawScalar: RawScalarTrait> {
49 #[error("the argument of the function is invalid!")]
54 InvalidArgument {
55 #[source]
57 #[backtrace]
58 source: RawScalar::ValidationError,
59 },
60}
61
62#[derive(Debug, Error)]
79pub enum TanRealInputErrors<RawReal: RawRealTrait> {
80 #[error("the argument ({value}) is a mathematical pole for the tangent function!")]
82 ArgumentIsPole {
83 value: RawReal,
85 backtrace: Backtrace,
87 },
88
89 #[error("the argument of the function is invalid!")]
94 InvalidArgument {
95 #[source]
97 #[backtrace]
98 source: <RawReal as RawScalarValidate>::ValidationError,
99 },
100}
101
102#[derive(Debug, Error)]
113pub enum ATanRealInputErrors<RawReal: RawRealTrait> {
114 #[error("the argument of the function is invalid!")]
119 InvalidArgument {
120 #[source]
122 #[backtrace]
123 source: RawReal::ValidationError,
124 },
125}
126
127#[duplicate_item(
131 enum_name enum_doc;
132 [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 RawScalarValidate>::ValidationError` (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."];
133 [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 RawScalarValidate>::ValidationError` (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."];
134)]
135#[derive(Debug, Error)]
136#[doc = enum_doc]
137pub enum enum_name<RawReal: RawRealTrait> {
138 #[error("the argument of the function ({value}) is not in the domain [-1.,1.]!")]
140 OutOfDomain {
141 value: RawReal,
143
144 backtrace: Backtrace,
146 },
147
148 #[error("the argument of the function is invalid!")]
153 InvalidArgument {
154 #[source]
156 #[backtrace]
157 source: <RawReal as RawScalarValidate>::ValidationError,
158 },
159}
160
161#[duplicate_item(
165 enum_name ErrIn enum_doc;
166 [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::ValidationError`.\n\n# Variants\n\n- `Input { source: ErrIn<RawScalar> }`: Input was invalid (e.g., NaN, Infinity).\n- `Output { source: RawScalar::ValidationError }`: Computed output was invalid (e.g., NaN, Infinity)."];
167 [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::ValidationError`.\n\n# Variants\n\n- `Input { source: ErrIn<RawScalar> }`: Input was invalid (e.g., NaN, Infinity).\n- `Output { source: RawScalar::ValidationError }`: Computed output was invalid (e.g., NaN, Infinity)."];
168)]
169#[doc = enum_doc]
170pub type enum_name<RawScalar> =
171 FunctionErrors<ErrIn<RawScalar>, <RawScalar as RawScalarValidate>::ValidationError>;
172
173#[duplicate_item(
177 enum_name ErrIn enum_doc;
178 [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 RawScalarValidate>::ValidationError`.\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 RawScalarValidate>::ValidationError }`: Computed output was invalid (e.g., NaN, Infinity)."];
179 [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 RawScalarValidate>::ValidationError`.\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 RawScalarValidate>::ValidationError }`: Computed output was invalid (e.g., NaN, Infinity)."];
180 [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 RawScalarValidate>::ValidationError`.\n\n# Variants\n\n- `Input { source: ErrIn<RawReal> }`: Input was invalid (e.g., NaN, Infinity).\n- `Output { source: <RawReal as RawScalarValidate>::ValidationError }`: Computed output was invalid (e.g., NaN, Infinity)."];
181 [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 RawScalarValidate>::ValidationError`.\n\n# Variants\n\n- `Input { source: ErrIn<RawReal> }`: Input was invalid (e.g., NaN, Infinity).\n- `Output { source: <RawReal as RawScalarValidate>::ValidationError }`: Computed output was invalid (e.g., NaN, Infinity)."];
182)]
183#[doc = enum_doc]
184pub type enum_name<RawReal> =
185 FunctionErrors<ErrIn<RawReal>, <RawReal as RawScalarValidate>::ValidationError>;
186
187#[duplicate_item(
191 enum_name enum_doc;
192 [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 RawScalarValidate>::ValidationError`.\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."];
193 [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 RawScalarValidate>::ValidationError`.\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."];
194 [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 RawScalarValidate>::ValidationError`.\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."];
195)]
196#[derive(Debug, Error)]
197#[doc = enum_doc]
198pub enum enum_name<RawComplex: RawComplexTrait> {
199 #[error("the argument of the function is invalid!")]
204 InvalidArgument {
205 #[source]
207 #[backtrace]
208 source: <RawComplex as RawScalarValidate>::ValidationError,
209 },
210}
211
212#[derive(Debug, Error)]
224pub enum ATanComplexInputErrors<RawComplex: RawComplexTrait> {
225 #[error("the argument ({value:?}) is a pole for the function!")]
229 ArgumentIsPole {
230 value: RawComplex,
232
233 backtrace: std::backtrace::Backtrace,
235 },
236
237 #[error("the argument of the function is invalid!")]
242 InvalidArgument {
243 #[source]
245 #[backtrace]
246 source: <RawComplex as RawScalarValidate>::ValidationError,
247 },
248}
249
250#[duplicate_item(
254 enum_name ErrIn enum_doc;
255 [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 RawScalarValidate>::ValidationError`.\n\n# Variants\n\n- `Input { source: ErrIn<RawComplex> }`: Input was invalid (e.g., components are NaN, Infinity).\n- `Output { source: <RawComplex as RawScalarValidate>::ValidationError }`: Computed output was invalid (e.g., components are NaN, Infinity)."];
256 [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 RawScalarValidate>::ValidationError`.\n\n# Variants\n\n- `Input { source: ErrIn<RawComplex> }`: Input was invalid (e.g., components are NaN, Infinity).\n- `Output { source: <RawComplex as RawScalarValidate>::ValidationError }`: Computed output was invalid (e.g., components are NaN, Infinity)."];
257 [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 RawScalarValidate>::ValidationError`.\n\n# Variants\n\n- `Input { source: ErrIn<RawComplex> }`: Input was invalid (e.g., components are NaN, Infinity).\n- `Output { source: <RawComplex as RawScalarValidate>::ValidationError }`: Computed output was invalid (e.g., components are NaN, Infinity)."];
258 [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 RawScalarValidate>::ValidationError`.\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 RawScalarValidate>::ValidationError }`: Computed output was invalid (e.g., components are NaN, Infinity)."];
259)]
260#[doc = enum_doc]
261pub type enum_name<RawComplex> =
262 FunctionErrors<ErrIn<RawComplex>, <RawComplex as RawScalarValidate>::ValidationError>;
263
264#[duplicate_item(
268 trait_name try_func func trait_doc try_func_doc func_doc err_doc;
269 [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."];
270 [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."];
271 [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."];
272 [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."];
273 [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."];
274 [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."];
275)]
276#[doc = trait_doc]
277pub trait trait_name: Sized {
278 #[doc = err_doc]
279 type Error: std::error::Error;
280
281 #[doc = try_func_doc]
282 #[must_use = "this `Result` may contain an error that should be handled"]
283 fn try_func(self) -> Result<Self, <Self as trait_name>::Error>;
284
285 #[doc = func_doc]
286 fn func(self) -> Self;
287}
288
289#[duplicate_item(
290 type_name trait_name Err ErrIn try_func func;
291 [T] [Sin] [SinErrors] [SinInputErrors] [try_sin] [sin];
292 [Complex::<T>] [Sin] [SinErrors] [SinInputErrors] [try_sin] [sin];
293 [T] [Cos] [CosErrors] [CosInputErrors] [try_cos] [cos];
294 [Complex::<T>] [Cos] [CosErrors] [CosInputErrors] [try_cos] [cos];
295 [T] [ATan] [ATanRealErrors] [ATanRealInputErrors] [try_atan] [atan];
296)]
297impl<T> trait_name for type_name
298where
299 T: NativeReal,
300{
301 type Error = Err<type_name>;
302
303 #[inline(always)]
304 fn try_func(self) -> Result<Self, Self::Error> {
305 #[cfg(debug_assertions)]
306 {
307 self.validate_raw_scalar()
308 .map_err(|e| ErrIn::InvalidArgument { source: e }.into())
309 .and_then(|v| {
310 type_name::func(v)
311 .validate_raw_scalar()
312 .map_err(|e| Err::Output { source: e })
313 })
314 }
315 #[cfg(not(debug_assertions))]
316 {
317 Ok(type_name::func(self))
318 }
319 }
320
321 #[inline(always)]
322 fn func(self) -> Self {
323 #[cfg(debug_assertions)]
324 {
325 self.try_func().unwrap()
326 }
327 #[cfg(not(debug_assertions))]
328 {
329 type_name::func(self)
330 }
331 }
332}
333
334#[duplicate_item(
335 type_name trait_name Err ErrIn try_func func;
336 [Complex::<T>] [Tan] [TanComplexErrors] [TanComplexInputErrors] [try_tan] [tan];
337 [Complex::<T>] [ASin] [ASinComplexErrors] [ASinComplexInputErrors] [try_asin] [asin];
338 [Complex::<T>] [ACos] [ACosComplexErrors] [ACosComplexInputErrors] [try_acos] [acos];
339
340)]
341impl<T> trait_name for type_name
342where
343 Self: RawComplexTrait<RawReal = T>,
344 T: NativeReal,
345{
346 type Error = Err<type_name>;
347
348 #[inline(always)]
349 fn try_func(self) -> Result<Self, Self::Error> {
350 #[cfg(debug_assertions)]
351 {
352 self.validate_raw_scalar()
353 .map_err(|e| ErrIn::InvalidArgument { source: e }.into())
354 .and_then(|v| {
355 type_name::func(v)
356 .validate_raw_scalar()
357 .map_err(|e| Err::Output { source: e })
358 })
359 }
360 #[cfg(not(debug_assertions))]
361 {
362 Ok(type_name::func(self))
363 }
364 }
365
366 #[inline(always)]
367 fn func(self) -> Self {
368 #[cfg(debug_assertions)]
369 {
370 self.try_func().unwrap()
371 }
372 #[cfg(not(debug_assertions))]
373 {
374 type_name::func(self)
375 }
376 }
377}
378
379impl<T> Tan for T
380where
381 T: NativeReal,
382{
383 type Error = TanRealErrors<T>;
384
385 #[inline(always)]
386 fn try_tan(self) -> Result<Self, Self::Error> {
387 #[cfg(debug_assertions)]
388 {
389 self.validate_raw_scalar()
390 .map_err(|e| TanRealInputErrors::InvalidArgument { source: e }.into())
391 .and_then(|v| {
392 if <T as Zero>::is_zero(&<T as Float>::cos(v)) {
399 Err(TanRealInputErrors::ArgumentIsPole {
400 value: v,
401 backtrace: capture_backtrace(),
402 }
403 .into())
404 } else {
405 <T as Float>::tan(v)
406 .validate_raw_scalar()
407 .map_err(|e| TanRealErrors::Output { source: e })
408 }
409 })
410 }
411 #[cfg(not(debug_assertions))]
412 {
413 Ok(<T as Float>::tan(self))
414 }
415 }
416
417 #[inline(always)]
418 fn tan(self) -> Self {
419 #[cfg(debug_assertions)]
420 {
421 self.try_tan().unwrap()
422 }
423 #[cfg(not(debug_assertions))]
424 {
425 <T as Float>::tan(self)
426 }
427 }
428}
429
430#[duplicate_item(
431 my_trait E ErrIn try_func func;
432 [ASin] [ASinRealErrors] [ASinRealInputErrors] [try_asin] [asin];
433 [ACos] [ACosRealErrors] [ACosRealInputErrors] [try_acos] [acos];
434)]
435impl<T> my_trait for T
436where
437 T: NativeReal,
438{
439 type Error = E<T>;
440
441 #[inline(always)]
442 fn try_func(self) -> Result<Self, <Self as my_trait>::Error> {
443 #[cfg(debug_assertions)]
444 {
445 self.validate_raw_scalar()
446 .map_err(|e| ErrIn::InvalidArgument { source: e }.into())
447 .and_then(|v| {
448 if !(T::negative_one()..=T::one()).contains(&v) {
449 Err(ErrIn::OutOfDomain {
450 value: v,
451 backtrace: capture_backtrace(),
452 }
453 .into())
454 } else {
455 <T as Float>::func(v)
456 .validate_raw_scalar()
457 .map_err(|e| E::Output { source: e })
458 }
459 })
460 }
461 #[cfg(not(debug_assertions))]
462 {
463 Ok(<T as Float>::func(self))
464 }
465 }
466
467 #[inline(always)]
468 fn func(self) -> Self {
469 #[cfg(debug_assertions)]
470 {
471 self.try_func().unwrap()
472 }
473 #[cfg(not(debug_assertions))]
474 {
475 <T as Float>::func(self)
476 }
477 }
478}
479
480impl<T> ATan for Complex<T>
481where
482 Self: RawComplexTrait<RawReal = T>,
483 T: NativeReal,
484{
485 type Error = ATanComplexErrors<Complex<T>>;
486
487 #[inline(always)]
488 fn try_atan(self) -> Result<Self, <Self as ATan>::Error> {
489 #[cfg(debug_assertions)]
490 {
491 if self.re == T::zero() && self.im.abs() == T::one() {
492 Err(ATanComplexInputErrors::ArgumentIsPole {
493 value: self,
494 backtrace: capture_backtrace(),
495 }
496 .into())
497 } else {
498 self.validate_raw_scalar()
499 .map_err(|e| ATanComplexInputErrors::InvalidArgument { source: e }.into())
500 .and_then(|v| {
501 Complex::<T>::atan(v)
502 .validate_raw_scalar()
503 .map_err(|e| Self::Error::Output { source: e })
504 })
505 }
506 }
507 #[cfg(not(debug_assertions))]
508 {
509 Ok(Complex::<T>::atan(self))
510 }
511 }
512
513 #[inline(always)]
514 fn atan(self) -> Self {
515 #[cfg(debug_assertions)]
516 {
517 self.try_atan().unwrap()
518 }
519 #[cfg(not(debug_assertions))]
520 {
521 Complex::<T>::atan(self)
522 }
523 }
524}
525
526#[derive(Debug, Error)]
540pub enum ATan2InputErrors<RawReal: RawRealTrait> {
541 #[error("the numerator is invalid!")]
547 InvalidNumerator {
548 #[source]
550 #[backtrace]
551 source: <RawReal as RawScalarValidate>::ValidationError,
552 },
553
554 #[error("the denominator is invalid!")]
560 InvalidDenominator {
561 #[source]
563 #[backtrace]
564 source: <RawReal as RawScalarValidate>::ValidationError,
565 },
566
567 #[error("the numerator and the denominator are both zero!")]
572 ZeroOverZero {
573 backtrace: Backtrace,
575 },
576}
577
578pub type ATan2Errors<RawReal> =
610 FunctionErrors<ATan2InputErrors<RawReal>, <RawReal as RawScalarValidate>::ValidationError>;
611
612pub trait ATan2: Sized {
673 type Error: std::error::Error;
675
676 #[must_use = "this `Result` may contain an error that should be handled"]
698 fn try_atan2(self, denominator: &Self) -> Result<Self, Self::Error>;
699
700 fn atan2(self, denominator: &Self) -> Self;
703}
704
705impl<T> ATan2 for T
706where
707 T: NativeReal,
708{
709 type Error = ATan2Errors<T>;
711
712 fn try_atan2(self, denominator: &Self) -> Result<Self, Self::Error> {
741 #[cfg(debug_assertions)]
742 {
743 denominator
745 .validate_raw_scalar_ref()
746 .map_err(|e| ATan2InputErrors::InvalidDenominator { source: e })?;
747
748 let numerator = self
750 .validate_raw_scalar()
751 .map_err(|e| ATan2InputErrors::InvalidNumerator { source: e })?;
752
753 let zero = T::zero();
758 if numerator == zero && *denominator == zero {
759 Err(ATan2InputErrors::ZeroOverZero {
760 backtrace: capture_backtrace(),
761 }
762 .into())
763 } else {
764 <T as Float>::atan2(self, *denominator)
765 .validate_raw_scalar()
766 .map_err(|e| ATan2Errors::Output { source: e })
767 }
768 }
769 #[cfg(not(debug_assertions))]
770 {
771 Ok(<T as Float>::atan2(self, *denominator))
772 }
773 }
774
775 fn atan2(self, denominator: &Self) -> Self {
798 #[cfg(debug_assertions)]
799 {
800 self.try_atan2(denominator).unwrap()
801 }
802 #[cfg(not(debug_assertions))]
803 {
804 <T as Float>::atan2(self, *denominator)
805 }
806 }
807}
808pub trait TrigonometricFunctions: Sin + ASin + Cos + ACos + Tan + ATan {}
849
850impl<T> TrigonometricFunctions for T where T: Sin + ASin + Cos + ACos + Tan + ATan {}
851#[cfg(test)]
855mod tests {
856 use super::*;
857 use approx::assert_ulps_eq;
858 use num::Complex;
859
860 #[cfg(feature = "rug")]
861 use crate::backends::rug::validated::{ComplexRugStrictFinite, RealRugStrictFinite};
862
863 #[cfg(feature = "rug")]
864 use try_create::TryNew;
865
866 mod sin {
867 use super::*;
868
869 mod native {
870 use super::*;
871
872 mod real {
873 use super::*;
874
875 #[test]
876 fn sin_valid() {
877 let value = 4.0;
878 let expected_result = -0.7568024953079282;
879 assert_ulps_eq!(value.try_sin().unwrap(), expected_result);
880 assert_ulps_eq!(<f64 as Float>::sin(value), expected_result);
881 assert_ulps_eq!(<f64 as Sin>::sin(value), expected_result);
882 }
883
884 #[test]
885 fn sin_negative() {
886 let value = -4.0;
887 let expected_result = 0.7568024953079282;
888 assert_ulps_eq!(value.try_sin().unwrap(), expected_result);
889 assert_ulps_eq!(<f64 as Float>::sin(value), expected_result);
890 assert_ulps_eq!(<f64 as Sin>::sin(value), expected_result);
891 }
892
893 #[test]
894 fn sin_zero() {
895 let value = 0.0;
896 assert_eq!(value.try_sin().unwrap(), 0.0);
897 assert_eq!(<f64 as Float>::sin(value), 0.0);
898 assert_eq!(<f64 as Sin>::sin(value), 0.0);
899 }
900
901 #[test]
902 #[cfg(debug_assertions)]
903 fn sin_nan() {
904 let value = f64::NAN;
905 let result = value.try_sin();
906 assert!(matches!(result, Err(SinErrors::Input(..))));
907 }
908
909 #[test]
910 #[cfg(debug_assertions)]
911 fn sin_infinity() {
912 let value = f64::INFINITY;
913 assert!(matches!(value.try_sin(), Err(SinErrors::Input(..))));
914 }
915
916 #[test]
917 #[cfg(debug_assertions)]
918 fn sin_subnormal() {
919 let value = f64::MIN_POSITIVE / 2.0;
920 assert!(matches!(value.try_sin(), Err(SinErrors::Input(..))));
921 }
922 }
923
924 mod complex {
925 use super::*;
926
927 #[test]
928 fn sin_valid() {
929 let value = Complex::new(4.0, 1.0);
930 let expected_result = if cfg!(target_arch = "x86_64") {
931 Complex::new(-1.1678072748895183, -0.7681627634565731)
932 } else if cfg!(target_arch = "aarch64") {
933 Complex::new(-1.1678072748895185, -0.7681627634565731)
934 } else {
935 todo!("Architecture not-tested");
936 };
937
938 assert_eq!(value.try_sin().unwrap(), expected_result);
939 assert_eq!(<Complex<f64> as Sin>::sin(value), expected_result);
940 assert_eq!(value.sin(), expected_result);
941 }
942
943 #[test]
944 fn sin_zero() {
945 let value = Complex::new(0.0, 0.0);
946 let expected_result = Complex::new(0.0, 0.0);
947 assert_eq!(value.try_sin().unwrap(), expected_result);
948 assert_eq!(value.sin(), expected_result);
949 }
950
951 #[test]
952 #[cfg(debug_assertions)]
953 fn sin_nan() {
954 let value = Complex::new(f64::NAN, 0.0);
955 assert!(matches!(value.try_sin(), Err(SinErrors::Input(..))));
956
957 let value = Complex::new(0.0, f64::NAN);
958 assert!(matches!(value.try_sin(), Err(SinErrors::Input(..))));
959 }
960
961 #[test]
962 #[cfg(debug_assertions)]
963 fn sin_infinity() {
964 let value = Complex::new(f64::INFINITY, 0.0);
965 assert!(matches!(value.try_sin(), Err(SinErrors::Input(..))));
966
967 let value = Complex::new(0.0, f64::INFINITY);
968 assert!(matches!(value.try_sin(), Err(SinErrors::Input(..))));
969 }
970
971 #[test]
972 #[cfg(debug_assertions)]
973 fn sin_subnormal() {
974 let value = Complex::new(f64::MIN_POSITIVE / 2.0, 0.0);
975 assert!(matches!(value.try_sin(), Err(SinErrors::Input(..))));
976
977 let value = Complex::new(0.0, f64::MIN_POSITIVE / 2.0);
978 assert!(matches!(value.try_sin(), Err(SinErrors::Input(..))));
979 }
980 }
981 }
982
983 #[cfg(feature = "rug")]
984 mod rug53 {
985 use super::*;
986
987 mod real {
988 use super::*;
989
990 #[test]
991 fn test_rug_float_sin_valid() {
992 let value =
993 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, -4.0)).unwrap();
994
995 let expected_result = RealRugStrictFinite::<53>::try_new(rug::Float::with_val(
996 53,
997 7.568024953079282e-1,
998 ))
999 .unwrap();
1000 assert_eq!(value.clone().try_sin().unwrap(), expected_result);
1001 assert_eq!(value.sin(), expected_result);
1002 }
1003
1004 #[test]
1005 fn test_rug_float_sin_zero() {
1006 let value =
1007 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.0)).unwrap();
1008
1009 let expected_result =
1010 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.0)).unwrap();
1011 assert_eq!(value.clone().try_sin().unwrap(), expected_result);
1012 assert_eq!(value.sin(), expected_result);
1013 }
1014 }
1015
1016 mod complex {
1017 use super::*;
1018
1019 #[test]
1020 fn test_complex_rug_float_sin_valid() {
1021 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1022 53,
1023 (rug::Float::with_val(53, 4.0), rug::Float::with_val(53, 1.0)),
1024 ))
1025 .unwrap();
1026
1027 let expected_result =
1028 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1029 53,
1030 (
1031 rug::Float::with_val(53, -1.1678072748895185),
1032 rug::Float::with_val(53, -7.681627634565731e-1),
1033 ),
1034 ))
1035 .unwrap();
1036 assert_eq!(value.clone().try_sin().unwrap(), expected_result);
1037 assert_eq!(value.sin(), expected_result);
1038 }
1039
1040 #[test]
1041 fn test_complex_rug_float_sin_zero() {
1042 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1043 53,
1044 (rug::Float::with_val(53, 0.0), rug::Float::with_val(53, 0.0)),
1045 ))
1046 .unwrap();
1047
1048 let expected_result =
1049 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1050 53,
1051 (rug::Float::with_val(53, 0.), rug::Float::with_val(53, 0.)),
1052 ))
1053 .unwrap();
1054 assert_eq!(value.clone().try_sin().unwrap(), expected_result);
1055 assert_eq!(value.sin(), expected_result);
1056 }
1057 }
1058 }
1059 }
1060
1061 mod cos {
1062 use super::*;
1063
1064 mod native {
1065 use super::*;
1066
1067 mod real {
1068 use super::*;
1069
1070 #[test]
1071 fn cos_valid() {
1072 let value = 4.0;
1073 let expected_result = -0.6536436208636119;
1074 assert_eq!(value.try_cos().unwrap(), expected_result);
1075 assert_ulps_eq!(<f64 as Float>::cos(value), expected_result);
1076 assert_ulps_eq!(<f64 as Cos>::cos(value), expected_result);
1077 }
1078
1079 #[test]
1080 fn cos_negative() {
1081 let value = -4.0;
1082 let expected_result = -0.6536436208636119;
1083 assert_eq!(value.try_cos().unwrap(), expected_result);
1084 assert_ulps_eq!(<f64 as Float>::cos(value), expected_result);
1085 assert_ulps_eq!(<f64 as Cos>::cos(value), expected_result);
1086 }
1087
1088 #[test]
1089 fn cos_zero() {
1090 let value = 0.0;
1091 assert_eq!(value.try_cos().unwrap(), 1.0);
1092 assert_ulps_eq!(<f64 as Float>::cos(value), 1.0);
1093 assert_ulps_eq!(<f64 as Cos>::cos(value), 1.0);
1094 }
1095
1096 #[test]
1097 #[cfg(debug_assertions)]
1098 fn cos_nan() {
1099 let value = f64::NAN;
1100 let result = value.try_cos();
1101 assert!(matches!(result, Err(CosErrors::Input(..))));
1102 }
1103
1104 #[test]
1105 #[cfg(debug_assertions)]
1106 fn cos_infinity() {
1107 let value = f64::INFINITY;
1108 assert!(matches!(value.try_cos(), Err(CosErrors::Input(..))));
1109 }
1110
1111 #[test]
1112 #[cfg(debug_assertions)]
1113 fn cos_subnormal() {
1114 let value = f64::MIN_POSITIVE / 2.0;
1115 assert!(matches!(value.try_cos(), Err(CosErrors::Input(..))));
1116 }
1117 }
1118
1119 mod complex {
1120 use super::*;
1121
1122 #[test]
1123 fn cos_valid() {
1124 let value = Complex::new(4.0, 1.0);
1125 let expected_result = if cfg!(target_arch = "x86_64") {
1126 Complex::new(-1.0086248134251568, 0.8893951958384846)
1127 } else if cfg!(target_arch = "aarch64") {
1128 Complex::new(-1.0086248134251568, 0.8893951958384847)
1129 } else {
1130 todo!("Architecture not-tested");
1131 };
1132 assert_eq!(value.try_cos().unwrap(), expected_result);
1133 assert_eq!(<Complex<f64> as Cos>::cos(value), expected_result);
1134 assert_eq!(value.cos(), expected_result);
1135 }
1136
1137 #[test]
1138 fn cos_zero() {
1139 let value = Complex::new(0.0, 0.0);
1140 let expected_result = Complex::new(1.0, 0.0);
1141 assert_eq!(value.try_cos().unwrap(), expected_result);
1142 assert_eq!(value.cos(), expected_result);
1143 }
1144
1145 #[test]
1146 #[cfg(debug_assertions)]
1147 fn cos_nan() {
1148 let value = Complex::new(f64::NAN, 0.0);
1149 assert!(matches!(value.try_cos(), Err(CosErrors::Input(..))));
1150
1151 let value = Complex::new(0.0, f64::NAN);
1152 assert!(matches!(value.try_cos(), Err(CosErrors::Input(..))));
1153 }
1154
1155 #[test]
1156 #[cfg(debug_assertions)]
1157 fn cos_infinity() {
1158 let value = Complex::new(f64::INFINITY, 0.0);
1159 assert!(matches!(value.try_cos(), Err(CosErrors::Input(..))));
1160
1161 let value = Complex::new(0.0, f64::INFINITY);
1162 assert!(matches!(value.try_cos(), Err(CosErrors::Input(..))));
1163 }
1164
1165 #[test]
1166 #[cfg(debug_assertions)]
1167 fn cos_subnormal() {
1168 let value = Complex::new(f64::MIN_POSITIVE / 2.0, 0.0);
1169 assert!(matches!(value.try_cos(), Err(CosErrors::Input(..))));
1170
1171 let value = Complex::new(0.0, f64::MIN_POSITIVE / 2.0);
1172 assert!(matches!(value.try_cos(), Err(CosErrors::Input(..))));
1173 }
1174 }
1175 }
1176
1177 #[cfg(feature = "rug")]
1178 mod rug53 {
1179 use super::*;
1180
1181 mod real {
1182 use super::*;
1183
1184 #[test]
1185 fn test_rug_float_cos_valid() {
1186 let value =
1187 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, -4.0)).unwrap();
1188
1189 let expected_result = RealRugStrictFinite::<53>::try_new(rug::Float::with_val(
1190 53,
1191 -0.6536436208636119,
1192 ))
1193 .unwrap();
1194 assert_eq!(value.clone().try_cos().unwrap(), expected_result);
1195 assert_eq!(value.cos(), expected_result);
1196 }
1197
1198 #[test]
1199 fn test_rug_float_cos_zero() {
1200 let value =
1201 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.0)).unwrap();
1202
1203 let expected_result =
1204 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 1.0)).unwrap();
1205 assert_eq!(value.clone().try_cos().unwrap(), expected_result);
1206 assert_eq!(value.cos(), expected_result);
1207 }
1208 }
1209
1210 mod complex {
1211 use super::*;
1212
1213 #[test]
1214 fn test_complex_rug_float_cos_valid() {
1215 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1216 53,
1217 (rug::Float::with_val(53, 4.0), rug::Float::with_val(53, 1.0)),
1218 ))
1219 .unwrap();
1220
1221 let expected_result =
1222 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1223 53,
1224 (
1225 rug::Float::with_val(53, -1.0086248134251568),
1226 rug::Float::with_val(53, 8.893951958384847e-1),
1227 ),
1228 ))
1229 .unwrap();
1230 assert_eq!(value.clone().try_cos().unwrap(), expected_result);
1231 assert_eq!(value.cos(), expected_result);
1232 }
1233
1234 #[test]
1235 fn test_complex_rug_float_cos_zero() {
1236 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1237 53,
1238 (rug::Float::with_val(53, 0.0), rug::Float::with_val(53, 0.0)),
1239 ))
1240 .unwrap();
1241
1242 let expected_result =
1243 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1244 53,
1245 (rug::Float::with_val(53, 1.), rug::Float::with_val(53, 0.)),
1246 ))
1247 .unwrap();
1248 assert_eq!(value.clone().try_cos().unwrap(), expected_result);
1249 assert_eq!(value.cos(), expected_result);
1250 }
1251 }
1252 }
1253 }
1254
1255 mod tan {
1256 use super::*;
1257
1258 mod native {
1259 use super::*;
1260
1261 mod real {
1262 use super::*;
1263
1264 #[test]
1265 fn tan_valid() {
1266 let value = 4.0;
1267 let expected_result = 1.1578212823495775;
1268 assert_eq!(value.try_tan().unwrap(), expected_result);
1269 assert_eq!(<f64 as Tan>::tan(value), expected_result);
1270 assert_eq!(value.tan(), expected_result);
1271 }
1272
1273 #[test]
1287 fn tan_negative() {
1288 let value = -4.0;
1289 let expected_result = -1.1578212823495775;
1290 assert_eq!(value.try_tan().unwrap(), expected_result);
1291 assert_eq!(<f64 as Float>::tan(value), expected_result);
1292 assert_eq!(<f64 as Tan>::tan(value), expected_result);
1293 }
1294
1295 #[test]
1296 fn tan_zero() {
1297 let value = 0.0;
1298 assert_eq!(value.try_tan().unwrap(), 0.0);
1299 assert_eq!(<f64 as Float>::tan(value), 0.0);
1300 assert_eq!(<f64 as Tan>::tan(value), 0.0);
1301 }
1302
1303 #[test]
1304 #[cfg(debug_assertions)]
1305 fn tan_nan() {
1306 let value = f64::NAN;
1307 let result = value.try_tan();
1308 assert!(matches!(result, Err(TanRealErrors::Input(..))));
1309 }
1310
1311 #[test]
1312 #[cfg(debug_assertions)]
1313 fn tan_infinity() {
1314 let value = f64::INFINITY;
1315 assert!(matches!(value.try_tan(), Err(TanRealErrors::Input(..))));
1316 }
1317
1318 #[test]
1319 #[cfg(debug_assertions)]
1320 fn tan_subnormal() {
1321 let value = f64::MIN_POSITIVE / 2.0;
1322 assert!(matches!(value.try_tan(), Err(TanRealErrors::Input(..))));
1323 }
1324 }
1325
1326 mod complex {
1327 use super::*;
1328
1329 #[test]
1330 fn tan_valid() {
1331 let value = Complex::new(4.0, 1.0);
1332 let expected_result = Complex::new(0.27355308280730734, 1.002810507583505);
1333 assert_eq!(value.try_tan().unwrap(), expected_result);
1334 assert_eq!(<Complex<f64> as Tan>::tan(value), expected_result);
1335 assert_eq!(value.tan(), expected_result);
1336 }
1337
1338 #[test]
1339 fn tan_zero() {
1340 let value = Complex::new(0.0, 0.0);
1341 let expected_result = Complex::new(0.0, 0.0);
1342 assert_eq!(value.try_tan().unwrap(), expected_result);
1343 assert_eq!(value.tan(), expected_result);
1344 }
1345
1346 #[test]
1347 #[cfg(debug_assertions)]
1348 fn tan_nan() {
1349 let value = Complex::new(f64::NAN, 0.0);
1350 assert!(matches!(value.try_tan(), Err(TanComplexErrors::Input(..))));
1351
1352 let value = Complex::new(0.0, f64::NAN);
1353 assert!(matches!(value.try_tan(), Err(TanComplexErrors::Input(..))));
1354 }
1355
1356 #[test]
1357 #[cfg(debug_assertions)]
1358 fn tan_infinity() {
1359 let value = Complex::new(f64::INFINITY, 0.0);
1360 assert!(matches!(value.try_tan(), Err(TanComplexErrors::Input(..))));
1361
1362 let value = Complex::new(0.0, f64::INFINITY);
1363 assert!(matches!(value.try_tan(), Err(TanComplexErrors::Input(..))));
1364 }
1365
1366 #[test]
1367 #[cfg(debug_assertions)]
1368 fn tan_subnormal() {
1369 let value = Complex::new(f64::MIN_POSITIVE / 2.0, 0.0);
1370 assert!(matches!(value.try_tan(), Err(TanComplexErrors::Input(..))));
1371
1372 let value = Complex::new(0.0, f64::MIN_POSITIVE / 2.0);
1373 assert!(matches!(value.try_tan(), Err(TanComplexErrors::Input(..))));
1374 }
1375 }
1376 }
1377
1378 #[cfg(feature = "rug")]
1379 mod rug53 {
1380 use super::*;
1381
1382 mod real {
1383 use super::*;
1384
1385 #[test]
1386 fn test_rug_float_tan_valid() {
1387 let value =
1388 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, -4.0)).unwrap();
1389
1390 let expected_result = RealRugStrictFinite::<53>::try_new(rug::Float::with_val(
1391 53,
1392 -1.1578212823495775,
1393 ))
1394 .unwrap();
1395 assert_eq!(value.clone().try_tan().unwrap(), expected_result);
1396 assert_eq!(value.tan(), expected_result);
1397 }
1398
1399 #[cfg(feature = "rug")]
1400 #[test]
1401 fn test_rug_float_tan_zero() {
1402 let value =
1403 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.0)).unwrap();
1404
1405 let expected_result =
1406 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.0)).unwrap();
1407 assert_eq!(value.clone().try_tan().unwrap(), expected_result);
1408 assert_eq!(value.tan(), expected_result);
1409 }
1410
1411 }
1436
1437 mod complex {
1438 use super::*;
1439
1440 #[test]
1441 fn test_complex_rug_float_tan_valid() {
1442 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1443 53,
1444 (rug::Float::with_val(53, 4.0), rug::Float::with_val(53, 1.0)),
1445 ))
1446 .unwrap();
1447
1448 let expected_result =
1449 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1450 53,
1451 (
1452 rug::Float::with_val(53, 2.7355308280730734e-1),
1453 rug::Float::with_val(53, 1.002810507583505),
1454 ),
1455 ))
1456 .unwrap();
1457 assert_eq!(value.clone().try_tan().unwrap(), expected_result);
1458 assert_eq!(value.tan(), expected_result);
1459 }
1460
1461 #[test]
1462 fn test_complex_rug_float_tan_zero() {
1463 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1464 53,
1465 (rug::Float::with_val(53, 0.0), rug::Float::with_val(53, 0.0)),
1466 ))
1467 .unwrap();
1468
1469 let expected_result =
1470 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1471 53,
1472 (rug::Float::with_val(53, 0.), rug::Float::with_val(53, 0.)),
1473 ))
1474 .unwrap();
1475 assert_eq!(value.clone().try_tan().unwrap(), expected_result);
1476 assert_eq!(value.tan(), expected_result);
1477 }
1478
1479 }
1514 }
1515 }
1516
1517 mod atan {
1518 use super::*;
1519
1520 mod native {
1521 use super::*;
1522
1523 mod real {
1524 use super::*;
1525
1526 #[test]
1527 fn atan_valid() {
1528 let value = 4.0;
1529 let expected_result = 1.3258176636680326;
1530 assert_eq!(value.try_atan().unwrap(), expected_result);
1531 assert_eq!(<f64 as Float>::atan(value), expected_result);
1532 assert_eq!(<f64 as ATan>::atan(value), expected_result);
1533 }
1534
1535 #[test]
1536 fn atan_negative() {
1537 let value = -4.0;
1538 let expected_result = -1.3258176636680326;
1539 assert_eq!(value.try_atan().unwrap(), expected_result);
1540 assert_eq!(<f64 as Float>::atan(value), expected_result);
1541 assert_eq!(<f64 as ATan>::atan(value), expected_result);
1542 }
1543
1544 #[test]
1545 fn atan_zero() {
1546 let value = 0.0;
1547 assert_eq!(value.try_atan().unwrap(), 0.0);
1548 assert_eq!(<f64 as Float>::atan(value), 0.0);
1549 assert_eq!(<f64 as ATan>::atan(value), 0.0);
1550 }
1551 #[cfg(debug_assertions)]
1552 #[test]
1553 #[cfg(debug_assertions)]
1554 fn atan_nan() {
1555 let value = f64::NAN;
1556 let result = value.try_atan();
1557 assert!(matches!(result, Err(ATanRealErrors::Input(..))));
1558 }
1559
1560 #[test]
1561 #[cfg(debug_assertions)]
1562 fn atan_infinity() {
1563 let value = f64::INFINITY;
1564 assert!(matches!(value.try_atan(), Err(ATanRealErrors::Input(..))));
1565 }
1566
1567 #[test]
1568 #[cfg(debug_assertions)]
1569 fn atan_subnormal() {
1570 let value = f64::MIN_POSITIVE / 2.0;
1571 assert!(matches!(value.try_atan(), Err(ATanRealErrors::Input(..))));
1572 }
1573 }
1574
1575 mod complex {
1576 use super::*;
1577
1578 #[test]
1579 fn atan_valid() {
1580 let value = Complex::new(4.0, 1.0);
1581 let expected_result = Complex::new(1.3389725222944935, 0.05578588782855254);
1582 assert_eq!(value.try_atan().unwrap(), expected_result);
1583 assert_eq!(<Complex<f64> as ATan>::atan(value), expected_result);
1584 assert_eq!(value.atan(), expected_result);
1585 }
1586
1587 #[test]
1588 #[cfg(debug_assertions)]
1589 fn atan_out_of_domain() {
1590 let value = Complex::new(0.0, 1.0);
1591 let err = value.try_atan().unwrap_err();
1592 assert!(matches!(
1593 err,
1594 ATanComplexErrors::Input(ATanComplexInputErrors::ArgumentIsPole { .. })
1595 ));
1596
1597 let value = Complex::new(0.0, -1.0);
1598 let err = value.try_atan().unwrap_err();
1599 assert!(matches!(
1600 err,
1601 ATanComplexErrors::Input(ATanComplexInputErrors::ArgumentIsPole { .. })
1602 ));
1603 }
1604
1605 #[test]
1606 fn atan_zero() {
1607 let value = Complex::new(0.0, 0.0);
1608 let expected_result = Complex::new(0.0, 0.0);
1609 assert_eq!(value.try_atan().unwrap(), expected_result);
1610 assert_eq!(value.atan(), expected_result);
1611 }
1612
1613 #[test]
1614 #[cfg(debug_assertions)]
1615 fn atan_nan() {
1616 let value = Complex::new(f64::NAN, 0.0);
1617 assert!(matches!(
1618 value.try_atan(),
1619 Err(ATanComplexErrors::Input(..))
1620 ));
1621
1622 let value = Complex::new(0.0, f64::NAN);
1623 assert!(matches!(
1624 value.try_atan(),
1625 Err(ATanComplexErrors::Input(..))
1626 ));
1627 }
1628
1629 #[test]
1630 #[cfg(debug_assertions)]
1631 fn atan_infinity() {
1632 let value = Complex::new(f64::INFINITY, 0.0);
1633 assert!(matches!(
1634 value.try_atan(),
1635 Err(ATanComplexErrors::Input(..))
1636 ));
1637
1638 let value = Complex::new(0.0, f64::INFINITY);
1639 assert!(matches!(
1640 value.try_atan(),
1641 Err(ATanComplexErrors::Input(..))
1642 ));
1643 }
1644
1645 #[test]
1646 #[cfg(debug_assertions)]
1647 fn atan_subnormal() {
1648 let value = Complex::new(f64::MIN_POSITIVE / 2.0, 0.0);
1649 assert!(matches!(
1650 value.try_atan(),
1651 Err(ATanComplexErrors::Input(..))
1652 ));
1653
1654 let value = Complex::new(0.0, f64::MIN_POSITIVE / 2.0);
1655 assert!(matches!(
1656 value.try_atan(),
1657 Err(ATanComplexErrors::Input(..))
1658 ));
1659 }
1660 }
1661 }
1662
1663 #[cfg(feature = "rug")]
1664 mod rug53 {
1665 use super::*;
1666
1667 mod real {
1668 use super::*;
1669
1670 #[test]
1671 fn test_rug_float_atan_valid() {
1672 let value =
1673 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, -4.0)).unwrap();
1674
1675 let expected_result = RealRugStrictFinite::<53>::try_new(rug::Float::with_val(
1676 53,
1677 -1.3258176636680326,
1678 ))
1679 .unwrap();
1680 assert_eq!(value.clone().try_atan().unwrap(), expected_result);
1681 assert_eq!(value.atan(), expected_result);
1682 }
1683
1684 #[test]
1685 fn test_rug_float_atan_zero() {
1686 let value =
1687 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.0)).unwrap();
1688
1689 let expected_result =
1690 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.0)).unwrap();
1691 assert_eq!(value.clone().try_atan().unwrap(), expected_result);
1692 assert_eq!(value.atan(), expected_result);
1693 }
1694 }
1695
1696 mod complex {
1697 use super::*;
1698
1699 #[test]
1700 fn test_complex_rug_float_atan_valid() {
1701 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1702 53,
1703 (rug::Float::with_val(53, 4.0), rug::Float::with_val(53, 1.0)),
1704 ))
1705 .unwrap();
1706
1707 let expected_result =
1708 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1709 53,
1710 (
1711 rug::Float::with_val(53, 1.3389725222944935),
1712 rug::Float::with_val(53, 5.578588782855244e-2),
1713 ),
1714 ))
1715 .unwrap();
1716 assert_eq!(value.clone().try_atan().unwrap(), expected_result);
1717 assert_eq!(value.atan(), expected_result);
1718 }
1719
1720 #[test]
1721 fn test_complex_rug_float_atan_zero() {
1722 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1723 53,
1724 (rug::Float::with_val(53, 0.0), rug::Float::with_val(53, 0.0)),
1725 ))
1726 .unwrap();
1727
1728 let expected_result =
1729 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1730 53,
1731 (rug::Float::with_val(53, 0.), rug::Float::with_val(53, 0.)),
1732 ))
1733 .unwrap();
1734 assert_eq!(value.clone().try_atan().unwrap(), expected_result);
1735 assert_eq!(value.atan(), expected_result);
1736 }
1737 }
1738 }
1739 }
1740
1741 mod asin {
1742 use super::*;
1743
1744 mod native {
1745 use super::*;
1746
1747 mod real {
1748 use super::*;
1749
1750 #[test]
1751 fn asin_valid() {
1752 let value = 0.5;
1753 let expected_result = std::f64::consts::FRAC_PI_6;
1754
1755 assert_ulps_eq!(value.try_asin().unwrap(), expected_result);
1756 assert_ulps_eq!(value.asin(), expected_result);
1757 }
1758
1759 #[test]
1760 fn asin_negative() {
1761 let value = -0.5;
1762 let expected_result = -std::f64::consts::FRAC_PI_6;
1763
1764 assert_ulps_eq!(value.try_asin().unwrap(), expected_result);
1765 assert_ulps_eq!(value.asin(), expected_result);
1766 }
1767
1768 #[test]
1769 fn asin_zero() {
1770 let value = 0.0;
1771 assert_eq!(Float::asin(value), 0.0);
1772 assert_eq!(ASin::asin(value), 0.0);
1773 assert_eq!(value.try_asin().unwrap(), 0.0);
1774 }
1775
1776 #[test]
1777 #[cfg(debug_assertions)]
1778 fn asin_out_of_bound() {
1779 let value = 2.0;
1780 let result = value.try_asin();
1781 println!("result: {result:?}");
1782 assert!(matches!(result, Err(ASinRealErrors::Input(..))));
1783 }
1784
1785 #[test]
1786 #[cfg(debug_assertions)]
1787 fn asin_nan() {
1788 let value = f64::NAN;
1789 let result = value.try_asin();
1790 assert!(matches!(result, Err(ASinRealErrors::Input(..))));
1791 }
1792
1793 #[test]
1794 #[cfg(debug_assertions)]
1795 fn asin_infinity() {
1796 let value = f64::INFINITY;
1797 assert!(matches!(value.try_asin(), Err(ASinRealErrors::Input(..))));
1798 }
1799
1800 #[test]
1801 #[cfg(debug_assertions)]
1802 fn asin_subnormal() {
1803 let value = f64::MIN_POSITIVE / 2.0;
1804 assert!(matches!(value.try_asin(), Err(ASinRealErrors::Input(..))));
1805 }
1806 }
1807
1808 mod complex {
1809 use super::*;
1810
1811 #[test]
1812 fn asin_valid() {
1813 let value = Complex::new(0.5, 0.5);
1814 let expected_result = Complex::new(0.4522784471511907, 0.5306375309525178);
1815 assert_eq!(value.try_asin().unwrap(), expected_result);
1816 assert_eq!(<Complex<f64> as ASin>::asin(value), expected_result);
1817 assert_eq!(value.asin(), expected_result);
1818 }
1819
1820 #[test]
1821 fn asin_zero() {
1822 let value = Complex::new(0.0, 0.0);
1823 let expected_result = Complex::new(0.0, 0.0);
1824 assert_eq!(value.try_asin().unwrap(), expected_result);
1825 assert_eq!(value.asin(), expected_result);
1826 }
1827
1828 #[test]
1829 #[cfg(debug_assertions)]
1830 fn asin_nan() {
1831 let value = Complex::new(f64::NAN, 0.0);
1832 assert!(matches!(
1833 value.try_asin(),
1834 Err(ASinComplexErrors::Input(..))
1835 ));
1836
1837 let value = Complex::new(0.0, f64::NAN);
1838 assert!(matches!(
1839 value.try_asin(),
1840 Err(ASinComplexErrors::Input(..))
1841 ));
1842 }
1843
1844 #[test]
1845 #[cfg(debug_assertions)]
1846 fn asin_infinity() {
1847 let value = Complex::new(f64::INFINITY, 0.0);
1848 assert!(matches!(
1849 value.try_asin(),
1850 Err(ASinComplexErrors::Input(..))
1851 ));
1852
1853 let value = Complex::new(0.0, f64::INFINITY);
1854 assert!(matches!(
1855 value.try_asin(),
1856 Err(ASinComplexErrors::Input(..))
1857 ));
1858 }
1859
1860 #[test]
1861 #[cfg(debug_assertions)]
1862 fn asin_subnormal() {
1863 let value = Complex::new(f64::MIN_POSITIVE / 2.0, 0.0);
1864 assert!(matches!(
1865 value.try_asin(),
1866 Err(ASinComplexErrors::Input(..))
1867 ));
1868
1869 let value = Complex::new(0.0, f64::MIN_POSITIVE / 2.0);
1870 assert!(matches!(
1871 value.try_asin(),
1872 Err(ASinComplexErrors::Input(..))
1873 ));
1874 }
1875 }
1876 }
1877
1878 #[cfg(feature = "rug")]
1879 mod rug53 {
1880 use super::*;
1881
1882 mod real {
1883 use super::*;
1884
1885 #[test]
1886 fn asin_valid() {
1887 let value =
1888 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.5)).unwrap();
1889
1890 let expected_result = RealRugStrictFinite::<53>::try_new(rug::Float::with_val(
1891 53,
1892 std::f64::consts::FRAC_PI_6,
1893 ))
1894 .unwrap();
1895 assert_eq!(value.clone().try_asin().unwrap(), expected_result);
1896 assert_eq!(value.asin(), expected_result);
1897 }
1898
1899 #[test]
1900 fn asin_zero() {
1901 let value =
1902 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.0)).unwrap();
1903
1904 let expected_result =
1905 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.0)).unwrap();
1906 assert_eq!(value.clone().try_asin().unwrap(), expected_result);
1907 assert_eq!(value.asin(), expected_result);
1908 }
1909
1910 #[test]
1911 #[cfg(debug_assertions)]
1912 fn asin_out_of_bound() {
1913 let value =
1914 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 2.0)).unwrap();
1915 let result = value.try_asin();
1916 println!("result: {result:?}");
1917 assert!(matches!(result, Err(ASinRealErrors::Input(..))));
1918 }
1919 }
1920
1921 mod complex {
1922 use super::*;
1923
1924 #[test]
1925 fn asin_valid() {
1926 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1927 53,
1928 (rug::Float::with_val(53, 0.5), rug::Float::with_val(53, 0.5)),
1929 ))
1930 .unwrap();
1931
1932 let expected_result =
1933 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1934 53,
1935 (
1936 rug::Float::with_val(53, 0.4522784471511907),
1937 rug::Float::with_val(53, 0.5306375309525179),
1938 ),
1939 ))
1940 .unwrap();
1941 assert_eq!(value.clone().try_asin().unwrap(), expected_result);
1942 assert_eq!(value.asin(), expected_result);
1943 }
1944
1945 #[test]
1946 fn asin_zero() {
1947 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1948 53,
1949 (rug::Float::with_val(53, 0.0), rug::Float::with_val(53, 0.0)),
1950 ))
1951 .unwrap();
1952
1953 let expected_result =
1954 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
1955 53,
1956 (rug::Float::with_val(53, 0.), rug::Float::with_val(53, 0.)),
1957 ))
1958 .unwrap();
1959 assert_eq!(value.clone().try_asin().unwrap(), expected_result);
1960 assert_eq!(value.asin(), expected_result);
1961 }
1962 }
1963 }
1964 }
1965
1966 mod acos {
1967 use super::*;
1968
1969 mod native {
1970 use super::*;
1971
1972 mod real {
1973 use super::*;
1974
1975 #[test]
1976 fn acos_valid() {
1977 let value = 0.5;
1978 let expected_result = std::f64::consts::FRAC_PI_3;
1979
1980 assert_ulps_eq!(value.try_acos().unwrap(), expected_result);
1981 assert_ulps_eq!(value.acos(), expected_result);
1982 }
1983
1984 #[test]
1985 fn acos_negative() {
1986 let value = -0.5;
1987 let expected_result = 2.0943951023931957;
1988 assert_eq!(Float::acos(value), expected_result);
1989 assert_eq!(ACos::acos(value), expected_result);
1990 assert_eq!(value.try_acos().unwrap(), expected_result);
1991 }
1992
1993 #[test]
1994 fn acos_zero() {
1995 let value = 0.0;
1996 let expected_result = std::f64::consts::FRAC_PI_2;
1997 assert_eq!(Float::acos(value), expected_result);
1998 assert_eq!(ACos::acos(value), expected_result);
1999 assert_eq!(value.try_acos().unwrap(), expected_result);
2000 }
2001
2002 #[test]
2003 #[cfg(debug_assertions)]
2004 fn acos_out_of_bound() {
2005 let value = 2.0;
2006 let result = value.try_acos();
2007 println!("result: {result:?}");
2008 assert!(matches!(result, Err(ACosRealErrors::Input(..))));
2009 }
2010
2011 #[test]
2012 #[cfg(debug_assertions)]
2013 fn acos_nan() {
2014 let value = f64::NAN;
2015 let result = value.try_acos();
2016 assert!(matches!(result, Err(ACosRealErrors::Input(..))));
2017 }
2018
2019 #[test]
2020 #[cfg(debug_assertions)]
2021 fn acos_infinity() {
2022 let value = f64::INFINITY;
2023 assert!(matches!(value.try_acos(), Err(ACosRealErrors::Input(..))));
2024 }
2025
2026 #[test]
2027 #[cfg(debug_assertions)]
2028 fn acos_subnormal() {
2029 let value = f64::MIN_POSITIVE / 2.0;
2030 assert!(matches!(value.try_acos(), Err(ACosRealErrors::Input(..))));
2031 }
2032 }
2033
2034 mod complex {
2035 use super::*;
2036
2037 #[test]
2038 fn acos_valid() {
2039 let value = Complex::new(0.5, 0.5);
2040 let expected_result = Complex::new(1.118517879643706, -0.5306375309525179);
2041 assert_eq!(value.try_acos().unwrap(), expected_result);
2042 assert_eq!(<Complex<f64> as ACos>::acos(value), expected_result);
2043 assert_eq!(value.acos(), expected_result);
2044 }
2045
2046 #[test]
2047 fn acos_zero() {
2048 let value = Complex::new(0.0, 0.0);
2049 let expected_result = Complex::new(std::f64::consts::FRAC_PI_2, 0.0);
2050 assert_eq!(value.try_acos().unwrap(), expected_result);
2051 assert_eq!(value.acos(), expected_result);
2052 }
2053
2054 #[test]
2055 #[cfg(debug_assertions)]
2056 fn acos_nan() {
2057 let value = Complex::new(f64::NAN, 0.0);
2058 assert!(matches!(
2059 value.try_acos(),
2060 Err(ACosComplexErrors::Input(..))
2061 ));
2062
2063 let value = Complex::new(0.0, f64::NAN);
2064 assert!(matches!(
2065 value.try_acos(),
2066 Err(ACosComplexErrors::Input(..))
2067 ));
2068 }
2069
2070 #[test]
2071 #[cfg(debug_assertions)]
2072 fn acos_infinity() {
2073 let value = Complex::new(f64::INFINITY, 0.0);
2074 assert!(matches!(
2075 value.try_acos(),
2076 Err(ACosComplexErrors::Input(..))
2077 ));
2078
2079 let value = Complex::new(0.0, f64::INFINITY);
2080 assert!(matches!(
2081 value.try_acos(),
2082 Err(ACosComplexErrors::Input(..))
2083 ));
2084 }
2085
2086 #[test]
2087 #[cfg(debug_assertions)]
2088 fn acos_subnormal() {
2089 let value = Complex::new(f64::MIN_POSITIVE / 2.0, 0.0);
2090 assert!(matches!(
2091 value.try_acos(),
2092 Err(ACosComplexErrors::Input(..))
2093 ));
2094
2095 let value = Complex::new(0.0, f64::MIN_POSITIVE / 2.0);
2096 assert!(matches!(
2097 value.try_acos(),
2098 Err(ACosComplexErrors::Input(..))
2099 ));
2100 }
2101 }
2102 }
2103
2104 #[cfg(feature = "rug")]
2105 mod rug53 {
2106 use super::*;
2107
2108 mod real {
2109 use super::*;
2110
2111 #[test]
2112 fn acos_valid() {
2113 let value =
2114 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.5)).unwrap();
2115
2116 let expected_result = RealRugStrictFinite::<53>::try_new(rug::Float::with_val(
2117 53,
2118 std::f64::consts::FRAC_PI_3,
2119 ))
2120 .unwrap();
2121 assert_eq!(value.clone().try_acos().unwrap(), expected_result);
2122 assert_eq!(value.acos(), expected_result);
2123 }
2124
2125 #[test]
2126 fn acos_zero() {
2127 let value =
2128 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 0.0)).unwrap();
2129
2130 let expected_result = RealRugStrictFinite::<53>::try_new(rug::Float::with_val(
2131 53,
2132 std::f64::consts::FRAC_PI_2,
2133 ))
2134 .unwrap();
2135 assert_eq!(value.clone().try_acos().unwrap(), expected_result);
2136 assert_eq!(value.acos(), expected_result);
2137 }
2138
2139 #[test]
2140 #[cfg(debug_assertions)]
2141 fn acos_out_of_bound() {
2142 let value =
2143 RealRugStrictFinite::<53>::try_new(rug::Float::with_val(53, 2.0)).unwrap();
2144 let result = value.try_acos();
2145 println!("result: {result:?}");
2146 assert!(matches!(result, Err(ACosRealErrors::Input(..))));
2147 }
2148 }
2149
2150 mod complex {
2151 use super::*;
2152
2153 #[test]
2154 fn acos_valid() {
2155 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
2156 53,
2157 (rug::Float::with_val(53, 0.5), rug::Float::with_val(53, 0.5)),
2158 ))
2159 .unwrap();
2160
2161 let expected_result =
2162 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
2163 53,
2164 (
2165 rug::Float::with_val(53, 1.1185178796437059),
2166 rug::Float::with_val(53, -5.306375309525179e-1),
2167 ),
2168 ))
2169 .unwrap();
2170 assert_eq!(value.clone().try_acos().unwrap(), expected_result);
2171 assert_eq!(value.acos(), expected_result);
2172 }
2173
2174 #[test]
2175 fn acos_zero() {
2176 let value = ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
2177 53,
2178 (rug::Float::with_val(53, 0.0), rug::Float::with_val(53, 0.0)),
2179 ))
2180 .unwrap();
2181
2182 let expected_result =
2183 ComplexRugStrictFinite::<53>::try_new(rug::Complex::with_val(
2184 53,
2185 (
2186 rug::Float::with_val(53, std::f64::consts::FRAC_PI_2),
2187 rug::Float::with_val(53, 0.),
2188 ),
2189 ))
2190 .unwrap();
2191 assert_eq!(value.clone().try_acos().unwrap(), expected_result);
2192 assert_eq!(value.acos(), expected_result);
2193 }
2194 }
2195 }
2196 }
2197
2198 mod atan2 {
2199 use super::*;
2200
2201 mod native {
2202 use super::*;
2203
2204 #[test]
2205 fn atan2_valid() {
2206 let numerator = 1.0;
2207 let denominator = 1.0;
2208 let expected_result = std::f64::consts::FRAC_PI_4; assert_eq!(Float::atan2(numerator, denominator), expected_result);
2210 assert_eq!(ATan2::atan2(numerator, &denominator), expected_result);
2211 assert_eq!(numerator.try_atan2(&denominator).unwrap(), expected_result);
2212 }
2213
2214 #[test]
2215 fn atan2_zero_numerator() {
2216 let numerator = 0.0;
2217 let denominator = 1.0;
2218 let expected_result = 0.0;
2219 assert_eq!(Float::atan2(numerator, denominator), expected_result);
2220 assert_eq!(ATan2::atan2(numerator, &denominator), expected_result);
2221 assert_eq!(numerator.try_atan2(&denominator).unwrap(), expected_result);
2222 }
2223
2224 #[test]
2225 fn atan2_zero_denominator() {
2226 let numerator = 1.0;
2227 let denominator = 0.0;
2228 let expected_result = std::f64::consts::FRAC_PI_2; assert_eq!(Float::atan2(numerator, denominator), expected_result);
2230 assert_eq!(ATan2::atan2(numerator, &denominator), expected_result);
2231 assert_eq!(numerator.try_atan2(&denominator).unwrap(), expected_result);
2232 }
2233
2234 #[test]
2235 #[cfg(debug_assertions)]
2236 fn atan2_zero_over_zero() {
2237 let numerator = 0.0;
2238 let denominator = 0.0;
2239 let result = numerator.try_atan2(&denominator);
2240 assert!(matches!(
2241 result,
2242 Err(ATan2Errors::Input(ATan2InputErrors::ZeroOverZero { .. }))
2243 ));
2244 }
2245
2246 #[test]
2247 fn atan2_negative_numerator() {
2248 let numerator = -1.0;
2249 let denominator = 1.0;
2250 let expected_result = -std::f64::consts::FRAC_PI_4; assert_eq!(Float::atan2(numerator, denominator), expected_result);
2252 assert_eq!(ATan2::atan2(numerator, &denominator), expected_result);
2253 assert_eq!(numerator.try_atan2(&denominator).unwrap(), expected_result);
2254 }
2255
2256 #[test]
2257 fn atan2_negative_denominator() {
2258 let numerator = 1.0;
2259 let denominator = -1.0;
2260 let expected_result = 2.356194490192345; assert_eq!(Float::atan2(numerator, denominator), expected_result);
2262 assert_eq!(ATan2::atan2(numerator, &denominator), expected_result);
2263 assert_eq!(numerator.try_atan2(&denominator).unwrap(), expected_result);
2264 }
2265
2266 #[test]
2267 #[cfg(debug_assertions)]
2268 fn atan2_nan_numerator() {
2269 let numerator = f64::NAN;
2270 let denominator = 1.0;
2271 let result = numerator.try_atan2(&denominator);
2272 assert!(result.is_err());
2273 }
2274
2275 #[test]
2276 #[cfg(debug_assertions)]
2277 fn atan2_nan_denominator() {
2278 let numerator = 1.0;
2279 let denominator = f64::NAN;
2280 let result = numerator.try_atan2(&denominator);
2281 assert!(result.is_err());
2282 }
2283 }
2284
2285 #[cfg(feature = "rug")]
2286 mod rug53 {
2287 use super::*;
2288 use rug::Float;
2289
2290 #[test]
2291 fn atan2_valid() {
2292 let numerator =
2293 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 1.0)).unwrap();
2294 let denominator =
2295 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 1.0)).unwrap();
2296 let expected_result = RealRugStrictFinite::<53>::try_new(Float::with_val(
2297 53,
2298 std::f64::consts::FRAC_PI_4,
2299 ))
2300 .unwrap(); assert_eq!(numerator.clone().atan2(&denominator), expected_result);
2302 assert_eq!(numerator.try_atan2(&denominator).unwrap(), expected_result);
2303 }
2304
2305 #[test]
2306 fn atan2_zero_numerator() {
2307 let numerator =
2308 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
2309 let denominator =
2310 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 1.0)).unwrap();
2311 let expected_result =
2312 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
2313 assert_eq!(numerator.clone().atan2(&denominator), expected_result);
2314 assert_eq!(numerator.try_atan2(&denominator).unwrap(), expected_result);
2315 }
2316
2317 #[test]
2318 fn atan2_zero_denominator() {
2319 let numerator =
2320 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 1.0)).unwrap();
2321 let denominator =
2322 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
2323 let expected_result = RealRugStrictFinite::<53>::try_new(Float::with_val(
2324 53,
2325 std::f64::consts::FRAC_PI_2,
2326 ))
2327 .unwrap(); assert_eq!(numerator.clone().atan2(&denominator), expected_result);
2329 assert_eq!(numerator.try_atan2(&denominator).unwrap(), expected_result);
2330 }
2331
2332 #[test]
2333 #[cfg(debug_assertions)]
2334 fn atan2_zero_over_zero() {
2335 let numerator =
2336 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
2337 let denominator =
2338 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
2339 let result = numerator.try_atan2(&denominator);
2340 assert!(matches!(
2341 result,
2342 Err(ATan2Errors::Input(ATan2InputErrors::ZeroOverZero { .. }))
2343 ));
2344 }
2345
2346 #[test]
2347 fn atan2_negative_numerator() {
2348 let numerator =
2349 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -1.0)).unwrap();
2350 let denominator =
2351 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 1.0)).unwrap();
2352 let expected_result = RealRugStrictFinite::<53>::try_new(Float::with_val(
2353 53,
2354 -std::f64::consts::FRAC_PI_4,
2355 ))
2356 .unwrap(); assert_eq!(numerator.clone().atan2(&denominator), expected_result);
2358 assert_eq!(numerator.try_atan2(&denominator).unwrap(), expected_result);
2359 }
2360
2361 #[test]
2362 fn atan2_negative_denominator() {
2363 let numerator =
2364 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 1.0)).unwrap();
2365 let denominator =
2366 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -1.0)).unwrap();
2367 let expected_result =
2368 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 2.356194490192345))
2369 .unwrap(); assert_eq!(numerator.clone().atan2(&denominator), expected_result);
2371 assert_eq!(numerator.try_atan2(&denominator).unwrap(), expected_result);
2372 }
2373 }
2374 }
2375}
2376