Jump to content

Posit numbers/decoding: Difference between revisions

m
→‎{{header|Julia}}: add 2's complement handling for negatives
(→‎{{header|Wren}}: Rewritten to deal with posit numbers of any size.)
m (→‎{{header|Julia}}: add 2's complement handling for negatives)
Line 14:
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">struct""" PositType3{T<:Integer}Posit number, a quotient of integers, variable size and exponent length """
struct PositType3{T<:Integer}
numbits::UInt16
es::UInt16
bits::T
PositType3(nb, ne, i) = new{typeof(i)}(UInt16(nb), UInt16(ne), i)
end
 
""" FromConvert PositType3 to Rational. See also posithub.org/docs/Posits4.pdf """
function Base.Rational(p::PositType3)
s = signbit(signed(p.bits)) # s for S signbit, is 1 if negative
pabs = p.bits << 1 # shiftShift off signbit (adds a 0 to F at LSB)
pabs == 0 && return s ? 1 // 0 : 0 // 1 # ifIf p is 0, return 0 or if s 1 error
expsigns =&& signbit(signed(pabs = (-p.bits) << 1) # exponentIf signp fromis 2ndnegative, bitflip nowto MSB2's complement
expsign = signbit(signed(pabs)) # Exponent sign from 2nd bit now MSB
r = expsign == 1 ? leading_ones(pabs) : leading_zeros(pabs) # r regime R size
k = expsign ? r - 1 : -r # k for the exponent calculation
pabs <<= (r + 1) # shiftShift off unwanted R bits
pabs >>= (r + 2) # shiftShift back for E, F
fsize = p.numbits - 1 - r - 1 - p.es # checkCheck how many F bits explicit
fe = fsize < 1 ? 1pabs : pabs >> fsize # Get E value
f = fsize < 1 ? 1 : 1 + (pabs & (2^fsize - 1)) // 2^fsize # Get F value. Can(1 beby missing -> 1default)
e = fsize < 1 ? pabs : pabs >> fsize # Get E value.
pw = 2^p.es * k + e
return pw >= 0 ? (-1)^s * f * big"2"^pw // 1 : (-1)^s * f // big"2"^(-pw)
end
 
@show Rational(PositType3(16, 3, 0b0000110111011101)) == 477 // 134217728
const tests = [
(16, 3, 0b0000110111011101),
(16, 3, 0b1000000000000000),
(16, 3, 0b0000000000000000),
(16, 1, 0b0110110010101000),
(16, 1, 0b1001001101011000),
(16, 2, 0b0000000000000001),
(16, 0, 0b0111111111111111),
(16, 6, 0b0111111111111110),
(8, 1, 0b01000000),
(8, 1, 0b11000000),
(8, 1, 0b00110000),
(8, 1, 0b00100000),
(8, 2, 0b00000001),
(8, 2, 0b01111111),
(8, 7, 0b01111110),
(32, 2, 0b00000000000000000000000000000001),
(32, 2, 0b01111111111111111111111111111111),
(32, 5, 0b01111111111111111111111111111110),
]
 
for t in tests
r = Rational(PositType3(t...))
println(string(t[3], base = 2, pad = t[1]), " => $r = ", float(r))
end
</syntaxhighlight>{{out}}
Line 72 ⟶ 73:
0000000000000000 => 0//1 = 0.0
0110110010101000 => 405//32 = 12.65625
1001001101011000 => -363405//409632 = -012.08862304687565625
0000000000000001 => 1//72057594037927936 = 1.387778780781445675529539585113525390625e-17
0111111111111111 => 16384//1 = 16384.0
Line 83 ⟶ 84:
01111111 => 16777216//1 = 1.6777216e+07
01111110 => 4562440617622195218641171605700291324893228507248559930579192517899275167208677386505912811317371399778642309573594407310688704721375437998252661319722214188251994674360264950082874192246603776//1 = 4.562440617622195218641171605700291324893228507248559930579192517899275167208677e+192
00000000000000000000000000000001 => 1//1329227995784915872903807060280344576 = 7.523163845262640050999913838222372338039459563341360137656010920181870460510254e-37
01111111111111111111111111111111 => 1329227995784915872903807060280344576//1 = 1.329227995784915872903807060280344576e+36
01111111111111111111111111111110 => 2269007733883335972287082669296112915239349672942191252221331572442536403137824056312817862695551072066953619064625508194663368599769448406663254670871573830845597595897613333042429214224697474472410882236254024057110212260250671521235807709272244389361641091086035023229622419456//1 = 2.269007733883335972287082669296112915239349672942191252221331572442536403137824e+279
</pre>
 
4,105

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.