Posit numbers/decoding: Difference between revisions

Content added Content deleted
m (→‎{{header|Phix}}: added es limit comment)
(→‎{{header|Julia}}: use big 2 to prevent overflows)
Line 19: Line 19:
bits::T
bits::T
PositType3(nb, ne, i) = new{typeof(i)}(UInt16(nb), UInt16(ne), i)
PositType3(nb, ne, i) = new{typeof(i)}(UInt16(nb), UInt16(ne), i)
end
""" From posithub.org/docs/Posits4.pdf """
function Base.Rational(p::PositType3)7
s = signbit(signed(p.bits)) # s for S signbit, is 1 if negative
pabs = p.bits << 1 # shift off signbit (adds a 0 to F at LSB)
pabs == 0 && return s ? 1 // 0 : 0 // 1 # if p is 0, return 0 or if s 1 error
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) # shift off unwanted R bits
pabs >>= (r + 2) # shift back for E, F
fsize = p.numbits - 1 - r - 1 - p.es # check how many F bits explicit
f = fsize < 1 ? 1 :
1 + (pabs & (2^fsize-1)) // 2^fsize # Get F value. Can be missing -> 1
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
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
""" From posithub.org/docs/Posits4.pdf """
function Base.Rational(p::PositType3)
r = Rational(PositType3(t...))
println(string(t[3], base=2, pad = t[1]), " => $r = ", float(r))
s = signbit(p.bits) # s for S signbit, is 1 if negative
pabs = p.bits << 1 # shift off signbit (adds a 0 to F at LSB)
pabs == 0 && return s ? 1 // 0 : 0 // 1 # if p is 0, return 0 if s = 0, error if s = 1
expsign = signbit(pabs) # exponent sign from 2nd bit now in MSB location
k = expsign == 1 ? leading_ones(pabs) : leading_zeros(pabs) # regime R bit count
scaling = 2^p.es * (expsign == 0 ? -1 : 1)
pabs <<= (k + 1) # shift off unwanted R bits
pabs >>= (k + 2) # shift back without the extra LSB bit
fsize = p.numbits - k - p.es - 2 # check how many F bits are actually explicit
fsize <= 0 && return 0 // 1 # missing F is 0
f = (pabs & (2^fsize - 1)) // 2^fsize # Get F value. Can be missing -> 0
e = pabs >> fsize # Get E value.
pw = (1 - 2s) * (scaling * k + e + s)
return pw >= 0 ? ((1 - 3s) + f) * 2^pw // 1 : ((1 - 3s) + f) // 2^(-pw)
end
end
</syntaxhighlight>{{out}}

<pre>
@show Rational(PositType3(16, 3, 0b0000110111011101)) == 477 // 134217728
</syntaxhighlight>{{out}} <pre> Rational(PositType3(16, 3, 0x0ddd)) == 477 // 134217728 = true</pre>
Rational(PositType3(16, 3, 0x0ddd)) == 477 // 134217728 = true
0000110111011101 => 477//134217728 = 3.553926944732666015625e-06
1000000000000000 => 1//0 = Inf
0000000000000000 => 0//1 = 0.0
0110110010101000 => 405//32 = 12.65625
1001001101011000 => -363//4096 = -0.088623046875
0000000000000001 => 1//72057594037927936 = 1.387778780781445675529539585113525390625e-17
0111111111111111 => 16384//1 = 16384.0
0111111111111110 => 28638903918474961204418783933674838490721739172170652529441449702311064005352904159345284265824628375429359509218999720074396860757073376700445026041564579620512874307979212102266801261478978776245040008231745247475930553606737583615358787106474295296//1 = 2.86389039184749612044187839336748384907217391721706525294414497023110640053529e+250
01000000 => 1//1 = 1.0
11000000 => -1//1 = -1.0
00110000 => 1//2 = 0.5
00100000 => 1//4 = 0.25
00000001 => 1//16777216 = 5.9604644775390625e-08
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>


=={{header|Phix}}==
=={{header|Phix}}==