Skip to content

Instantly share code, notes, and snippets.

@dpsanders
Created April 15, 2015 01:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dpsanders/321546d749370403e0bc to your computer and use it in GitHub Desktop.
Save dpsanders/321546d749370403e0bc to your computer and use it in GitHub Desktop.
const JL_FE_INEXACT = 0x20
const JL_FE_UNDERFLOW = 0x10
const JL_FE_OVERFLOW = 0x08
const JL_FE_DIVBYZERO = 0x04
const JL_FE_INVALID = 0x01
const JL_FE_TONEAREST = 0x0000
const JL_FE_UPWARD = 0x0800
const JL_FE_DOWNWARD = 0x0400
const JL_FE_TOWARDZERO = 0x0c00
@show JL_FE_INEXACT
# From Simon Byrne's pull request https://github.com/JuliaLang/julia/pull/6170
module FloatingPointExceptions
include("fenv_constants.jl")
## floating point exceptions ##
import Base: show, in, convert
export FloatExceptions, FEInexact, FEUnderflow, FEOverflow, FEDivByZero, FEInvalid, FloatExceptionSet,
FEAll, clear_floatexcept, get_floatexcept, is_floatexcept
abstract FloatExceptions
immutable FEInexact <: FloatExceptions end
immutable FEUnderflow <: FloatExceptions end
immutable FEOverflow <: FloatExceptions end
immutable FEDivByZero <: FloatExceptions end
immutable FEInvalid <: FloatExceptions end
# IEEE 754 requires the ability to check/set/clear multiple exceptions
immutable FloatExceptionSet
flags::Cint
FloatExceptionSet(e::Integer) = new(convert(Cint,e))
end
convert(::Type{FloatExceptionSet},::Type{FEInexact}) = FloatExceptionSet(JL_FE_INEXACT)
convert(::Type{FloatExceptionSet},::Type{FEUnderflow}) = FloatExceptionSet(JL_FE_UNDERFLOW)
convert(::Type{FloatExceptionSet},::Type{FEOverflow}) = FloatExceptionSet(JL_FE_OVERFLOW)
convert(::Type{FloatExceptionSet},::Type{FEDivByZero}) = FloatExceptionSet(JL_FE_DIVBYZERO)
convert(::Type{FloatExceptionSet},::Type{FEInvalid}) = FloatExceptionSet(JL_FE_INVALID)
const FEAll = FloatExceptionSet(JL_FE_INEXACT | JL_FE_UNDERFLOW | JL_FE_OVERFLOW | JL_FE_DIVBYZERO | JL_FE_INVALID)
in(fs1::FloatExceptionSet,fs2::FloatExceptionSet) = fs1.flags & fs2.flags != zero(Cint)
in{E<:FloatExceptions}(::Type{E},fs::FloatExceptionSet) = in(convert(FloatExceptionSet,E), fs)
show(io::IO,fe::FloatExceptionSet) = showcompact(io, filter(x->in(x,fe),subtypes(FloatExceptions)))
# IEEE754 2008 5.7.4 requires the following functions:
# lowerFlags, raiseFlags, testFlags, testSavedFlags (handled by "in"), restoreFlags, saveAllFlags
# lowerFlags
function clear_floatexcept(f::FloatExceptionSet)
if ccall(:feclearexcept, Cint, (Cint,), f.flags) != zero(Cint)
error("Could not clear floating point exception flag")
end
end
clear_floatexcept{E<:FloatExceptions}(::Type{E}) = clear_floatexcept(convert(FloatExceptionSet,E))
clear_floatexcept() = clear_floatexcept(FEAll)
function get_floatexcept(f::FloatExceptionSet)
FloatExceptionSet(ccall(:fetestexcept, Cint, (Cint,), f.flags))
end
# saveAllFlags
get_floatexcept() = get_floatexcept(FEAll)
# testFlags
is_floatexcept(f::FloatExceptionSet) = in(f,get_floatexcept(f))
is_floatexcept{E<:FloatExceptions}(::Type{E}) = is_floatexcept(convert(FloatExceptionSet,E))
is_floatexcept() = is_floatexcept(FEAll)
# TODO: raiseFlags, restoreFlags
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment