-
Notifications
You must be signed in to change notification settings - Fork 2
/
Bitmanip.jl
93 lines (80 loc) · 2.66 KB
/
Bitmanip.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
module Bitmanip
using FloatProps
export visfinite, visinf, visnan, visnormal, vissubnormal, vsignbit
export vfabs, vflipsign, vcopysign, vneg
export vilogb, vldexp
@inline function visfinite{T}(x::T)
e = asInt(T,x) & exponent_mask(T)
return e != exponent_mask(T)
end
@inline function visinf{T}(x::T)
em = asInt(T,x) & (exponent_mask(T) | mantissa_mask(T))
return em == exponent_mask(T)
end
@inline function visnan{T}(x::T)
e = asInt(T,x) & exponent_mask(T)
m = asInt(T,x) & mantissa_mask(T)
return e == exponent_mask(T) && m != mkInt(T,0)
end
@inline function visnormal{T}(x::T)
e = asInt(T,x) & exponent_mask(T)
return e != exponent_mask(T) && e != mkInt(T,0)
end
@inline function vissubnormal{T}(x::T)
e = asInt(T,x) & exponent_mask(T)
m = asInt(T,x) & mantissa_mask(T)
return e == mkInt(T,0) && m != mkInt(T,0)
end
@inline function vsignbit{T}(x::T)
s = asInt(T,x) & signbit_mask(T)
return s != mkInt(T,0)
end
@inline function vfabs{T}(x::T)
return asFloat(T, asInt(T,x) & ~signbit_mask(T))
end
@inline function vflipsign{T}(x::T, y::T)
ix = asInt(T,x)
iysgn = asInt(T,y) & signbit_mask(T)
return asFloat(T, ix $ iysgn)
end
@inline function vcopysign{T}(x::T, y::T)
ixmag = asInt(T,x) & ~signbit_mask(T)
iysgn = asInt(T,y) & signbit_mask(T)
return asFloat(T, ixmag | iysgn)
end
@inline function vneg{T}(x::T)
return asFloat(T, asInt(T,x) $ signbit_mask(T))
end
@inline function vilogb{T}(x::T)
e = asInt(T,x) & exponent_mask(T) >> mantissa_bits(T) - exponent_offset(T)
return e
end
@inline function vldexp{T}(x::T, i::Integer)
i::intType(T)
# Use direct integer manipulation
# Extract integer as lowest mantissa bits (highest bits still
# contain offset, exponent, and sign)
ix = asInt(T,x)
# Construct scale factor by setting exponent (this shifts out the
# highest bits)
scale = asFloat(T, ix << mantissa_bits(T))
return x * scale
end
@inline function vldexp{T}(x::T, y::T)
# Use direct integer manipulation
# Add a large number to shift the integer bits into the rightmost
# bits of the mantissa. Also already add the exponent offset that
# we need below.
offset = mkFloat(T, mkInt(T,1) << mantissa_bits(T) + exponent_offset(T))
y = y + offset
# Extract integer as lowest mantissa bits (highest bits still
# contain offset, exponent, and sign)
iy = asInt(T,y)
# Construct scale factor by setting exponent. This shifts out the
# highest bits, and shifts the lowest mantissa bits into the
# exponent. We already added the exponent offset above.
scale = asFloat(T, iy << mantissa_bits(T))
r = x * scale
return r
end
end