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