Skip to content

Commit

Permalink
Better eps(); use hex values for fp traits; hex/oct/bin fp printing.
Browse files Browse the repository at this point in the history
The previous eps() improvements were part of the story, but not
all of it. See

https://en.wikipedia.org/wiki/Machine_epsilon#How_to_determine_machine_epsilon

for how to do it correctly -- this is what this version uses.

Allowing bin/oct/hex to print floating point values by their
bits makes it much easier to see what's going on with these
operations.

Removing the > and >= methods for floats since these are not
actually necessary: you can just swap the arguments, which is
what the fallback definition does anyway.
  • Loading branch information
StefanKarpinski committed Aug 17, 2011
1 parent dbe21a7 commit bc694cf
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 35 deletions.
50 changes: 25 additions & 25 deletions j/float.j
Original file line number Diff line number Diff line change
Expand Up @@ -102,40 +102,40 @@ rem(x::Float64, y::Float64) = boxf64(rem_float(unbox64(x), unbox64(y)))
< (x::Float64, y::Float64) = lt_float(unbox64(x),unbox64(y))
<=(x::Float32, y::Float32) = le_float(unbox32(x),unbox32(y))
<=(x::Float64, y::Float64) = le_float(unbox64(x),unbox64(y))
> (x::Float32, y::Float32) = gt_float(unbox32(x),unbox32(y))
> (x::Float64, y::Float64) = gt_float(unbox64(x),unbox64(y))
>=(x::Float32, y::Float32) = ge_float(unbox32(x),unbox32(y))
>=(x::Float64, y::Float64) = ge_float(unbox64(x),unbox64(y))

isequal(x::Float, y::Float) = (x == y) || (isnan(x) && isnan(y))

## constants ##
## floating point traits ##

Inf = 1/0
NaN = -(0/0)
Inf = boxf64(unbox64(0x7ff0000000000000))
NaN = boxf64(unbox64(0x7ff8000000000000))

pi() = 3.14159265358979323846
pi(x) = pi()
pi(::Union(Float64, Type{Float64})) = 3.14159265358979323846
pi(::Union(Float32, Type{Float32})) = float32(3.14159265358979323846)
@eval begin
inf(::Type{Float32}) = $float32(Inf)
nan(::Type{Float32}) = $float32(NaN)
inf(::Type{Float64}) = $Inf
nan(::Type{Float64}) = $NaN
inf{T<:Float}(x::T) = inf(T)
nan{T<:Float}(x::T) = nan(T)

## traits ##
typemin(::Type{Float32}) = $boxf32(unbox32(uint32(0x00800000)))
typemax(::Type{Float32}) = $boxf32(unbox32(uint32(0x7f7fffff)))
typemin(::Type{Float64}) = $boxf64(unbox64(0x0010000000000000))
typemax(::Type{Float64}) = $boxf64(unbox64(0x7fefffffffffffff))

eps(::Type{Float64}) = 2.2204460492503131e-16
@eval eps(::Type{Float32}) = $float32(1.19209289550781250e-07)
@eval function eps(x::Float64)
x == 0.0 ? $boxf64(unbox64(uint64(1))) :
isfinite(x) ? abs(x)*$eps(Float64) : $NaN
end
@eval function eps(x::Float32)
x == $float32(0.0) ? $boxf32(unbox32(uint32(1))) :
isfinite(x) ? abs(x)*$eps(Float32) : $float32(NaN)
eps(::Type{Float32}) = $boxf32(unbox32(uint32(0x34000000)))
eps(::Type{Float64}) = $boxf64(unbox64(0x3cb0000000000000))
end

typemin(::Type{Float32}) = float32(1.175494351e-38)
typemax(::Type{Float32}) = float32(3.402823466e+38)
typemin(::Type{Float64}) = 2.2250738585072014e-308
typemax(::Type{Float64}) = 1.7976931348623157e+308
eps(x::Float32) = isfinite(x) ? abs(boxf32(unbox32(boxsi32(unbox32(x))+int32(1)))-x) : nan(x)
eps(x::Float64) = isfinite(x) ? abs(boxf64(unbox64(boxsi64(unbox64(x))+int64(1)))-x) : nan(x)

sizeof(::Type{Float32}) = 4
sizeof(::Type{Float64}) = 8

## mathematical constants ##

pi() = 3.14159265358979323846
pi(x) = pi()
pi(::Union(Float64, Type{Float64})) = 3.14159265358979323846
pi(::Union(Float32, Type{Float32})) = float32(3.14159265358979323846)
21 changes: 11 additions & 10 deletions j/string.j
Original file line number Diff line number Diff line change
Expand Up @@ -781,20 +781,21 @@ function uint2str(n::Int, b::Int)
data, ulong(sz), uint64(n), uint32(b))
ASCIIString(data[1:(sz-1)]) # cut out terminating NUL
end

uint2str(n::Int, b::Int, len::Int) = lpad(uint2str(n,b),len,'0')
uint2str(n::Union(Int,Float), b::Int, len::Int) = lpad(uint2str(n,b),len,'0')
uint2str(x::Float64, b::Int) = uint2str(boxui64(unbox64(x)), b)
uint2str(x::Float32, b::Int) = uint2str(boxui32(unbox32(x)), b)

# TODO: support signed Ints too

bin(n::Int) = uint2str(n, 2)
oct(n::Int) = uint2str(n, 8)
dec(n::Int) = uint2str(n, 10)
hex(n::Int) = uint2str(n, 16)
bin(n::Union(Int,Float)) = uint2str(n, 2)
oct(n::Union(Int,Float)) = uint2str(n, 8)
dec(n::Union(Int,Float)) = uint2str(n, 10)
hex(n::Union(Int,Float)) = uint2str(n, 16)

bin(n::Int, l::Int) = lpad(bin(n), l, '0')
oct(n::Int, l::Int) = lpad(oct(n), l, '0')
dec(n::Int, l::Int) = lpad(dec(n), l, '0')
hex(n::Int, l::Int) = lpad(hex(n), l, '0')
bin(n::Union(Int,Float), l::Int) = lpad(bin(n), l, '0')
oct(n::Union(Int,Float), l::Int) = lpad(oct(n), l, '0')
dec(n::Union(Int,Float), l::Int) = lpad(dec(n), l, '0')
hex(n::Union(Int,Float), l::Int) = lpad(hex(n), l, '0')

## string to float functions ##

Expand Down

0 comments on commit bc694cf

Please sign in to comment.