Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

f32/64::asinh() should return -0.0 for -0.0 #63271

Closed
TimothyGu opened this issue Aug 4, 2019 · 2 comments · Fixed by #63698
Closed

f32/64::asinh() should return -0.0 for -0.0 #63271

TimothyGu opened this issue Aug 4, 2019 · 2 comments · Fixed by #63698
Labels
C-bug Category: This is a bug. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@TimothyGu
Copy link

Currently, both of the following return false:

(-0.0 as f64).asinh().is_sign_negative()
(-0.0 as f32).asinh().is_sign_negative()

However, in other languages like C, asinh(-0.0) would always return -0.0. We might need another fast case for 0.0 and -0.0 here:

rust/src/libstd/f64.rs

Lines 833 to 839 in f01b9f8

pub fn asinh(self) -> f64 {
if self == NEG_INFINITY {
NEG_INFINITY
} else {
(self + ((self * self) + 1.0).sqrt()).ln()
}
}

@jonas-schievink jonas-schievink added C-bug Category: This is a bug. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Aug 4, 2019
@nagisa
Copy link
Member

nagisa commented Aug 4, 2019

IEEE-754 (2008), section 9.2.1:

For the functions expm1, exp2m1, exp10m1, logp1, log2p1, log10p1, sin, tan, sinPi, atanPi, asin, atan, sinh, tanh, asinh, and atanh, f(+0) is +0 and f(−0) is −0 with no exception.

and

sinh(±∞) and asinh(±∞) are ±∞ with no exception.

@Phosphorus15
Copy link
Contributor

Phosphorus15 commented Aug 19, 2019

I don't think adding a fast case for -0.0 is enough, codes like

println!("{}", (-1e-20f64).asinh().is_sign_negative());

also reports to be false, considering that asinh is a monotone function.
(-0.0 as f64).asinh().is_sign_negative() and (-1e-20f64).asinh().is_sign_negative() should have the same result considering that -0.0 is strictly larger than -1e-20f.
Maybe it is more sound to add a case for any given floating number that is negative, and negate the result if it turns out not to be negative.

Centril added a commit to Centril/rust that referenced this issue Aug 27, 2019
Fixed floating point issue with asinh function

This should fixes rust-lang#63271 , in which `asinh(-0.0)` returns `0.0` instead of `-0.0`.
according to @nagisa
>
>
> IEEE-754 (2008), section 9.2.1:
>
> > For the functions expm1, exp2m1, exp10m1, logp1, log2p1, log10p1, sin, tan, sinPi, atanPi, asin, atan, sinh, tanh, asinh, and atanh, f(+0) is +0 and f(−0) is −0 with no exception.
>
> and
>
> > sinh(±∞) and asinh(±∞) are ±∞ with no exception.

After ensuring that the function `asinh` is the only function affected (functions like `sin`, `sinh` are all based on `cmath` library or `llvm` intrinsics), and that `atanh` always gives the correct result. The only function to modify is `asinh`.
@bors bors closed this as completed in 68597c7 Aug 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants