-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
hardware independent isinf/isnan/isfinite #19008
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,8 @@ | |
|
|
||
| ## floating point traits ## | ||
|
|
||
| typealias IEEEFloat Union{Float16,Float32,Float64} | ||
|
|
||
| """ | ||
| Inf16 | ||
|
|
||
|
|
@@ -494,17 +496,29 @@ abs(x::Float64) = box(Float64,abs_float(unbox(Float64,x))) | |
|
|
||
| Test whether a floating point number is not a number (NaN). | ||
| """ | ||
| isnan{T<:IEEEFloat}(x::T) = (reinterpret(Unsigned, x) & ~sign_mask(T)) > exponent_mask(T) | ||
| isnan(x::AbstractFloat) = x != x | ||
| isnan(x::Float16) = reinterpret(UInt16,x)&0x7fff > 0x7c00 | ||
| isnan(x::Real) = false | ||
|
|
||
| """ | ||
| isfinite(f) -> Bool | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this be removed from helpdb/Base.jl if it's also there and now duplicated? |
||
|
|
||
| Test whether a floating point number is finite, i.e. that `f` is neither infinite or not a number. | ||
| """ | ||
| isfinite{T<:IEEEFloat}(x::T) = (reinterpret(Unsigned, x) & exponent_mask(T)) != exponent_mask(T) | ||
| isfinite(x::AbstractFloat) = x - x == 0 | ||
| isfinite(x::Float16) = reinterpret(UInt16,x)&0x7c00 != 0x7c00 | ||
| isfinite(x::Real) = decompose(x)[3] != 0 | ||
| isfinite(x::Integer) = true | ||
|
|
||
| """ | ||
| isinf(f) -> Bool | ||
|
|
||
| Test whether a floating point number is an infinity value (positive infinity or negative infinity). | ||
| """ | ||
| isinf{T<:IEEEFloat}(x::T) = (reinterpret(Unsigned, x) & ~sign_mask(T)) == exponent_mask(T) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, is this more efficient? |
||
| isinf(x::Real) = !isnan(x) & !isfinite(x) | ||
|
|
||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unnecessary newline |
||
| ## hashing small, built-in numeric types ## | ||
|
|
||
| hx(a::UInt64, b::Float64, h::UInt) = hash_uint64((3a + reinterpret(UInt64,b)) - h) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool did not know
reinterpret(Unsigned, x)is a thing.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this more efficient than
x != x?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not
I don't think we should sacrifice losing this hardware instructions when available.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See https://gist.github.com/musm/8150451b04120ef27974d8270dedbf6f
for more comprehensive tests (the gist is we are comparing performance in the 10-100 picosecond range...) So basically these instructions are so cheap and fast that it really doesn't matter on modern processors. In other words, the changes are just as fast as what we already have.
For
isnanI agree, unfortunately we still require special handling forFloat16which prompted this pr, which I thought would be good to unify all the exceptional case handling to be independent of floating point hardware instructions so that Float16 (F128/F80) would be handled all the same. But the problem currently is that cpu support for small floats is not great (but I think now intel is investing more on this side due to demand).I'll leave this to @vchuravy expertise on the issue on whether these proposed changes are positive or not, for now I am closing this.
For the denormals even though
x - xwill not work. It's only on the x87 chips where exceptional handling are very bad (some x87 sandybridge too?), where one may want to disable or flush them to zero.But disabling denormals is not recommended, so the issue will probably never crop up; someone would have to go out of their way to disable them in Julia anyways.
So perhaps only for
isinfandisfinitethe changes are positive, but at that point might as well just use what we already have.