Posit numbers/decoding: Difference between revisions

(Added Wren)
Line 14:
=={{header|raku}}==
 
<syntaxhighlight lang=raku>unit role Posit[UInt $nbitsN, UInt $es];
 
has BoolUInt @.bits[$nbits].UInt;
method sign { self.UInt > 2**($N - 1) ?? -1 !! +1 }
 
method RealFatRat {
method Str { sprintf('%0b' x $nbits, @!bits) }
return Inf0 if self.UInt ~~== /^10*$/0;
sub useed { 2**(2**$es) }
my UInt $mask = 2**($N - 1);
return Inf if self.UInt == $mask;
my UInt $n = self.UInt;
my $sign = @!bits.head$n +& $mask ?? -1 !! +1;
my $r = $sign;
$n = ((2**$n - 1) +^ $n) + 1 if self.sign < 0;
my int $count = 0;
$mask +>= 1;
my myBool $first-bit = ?($/.Str.substr(0,1n +& $mask);
repeat { $count++; $mask +>= 1;
} while ?($n +& $mask) == $first-bit && $mask;
my $m = $count;
my $k = make useed**($first-bit eq '1' ?? $m - 1 !! -$m);
sub useed {$r *= 2**($k*2**$es) };
return 0$r unless @!bits.any$mask > 1;
$mask +>= 1;
$count = 0;
my UInt $exponent = 0;
while $mask && $count++ < $es {
$exponent +<= 1;
$exponent +|= 1 if $n +& $mask;
$mask +>= 1;
(}
$r *= 2**$exponent;
my token $fraction {= <1.bit>+ }FatRat;
while $mask {
(state $power-of-two = 1) +<= 1;
$fraction += 1/$power-of-two if $n +& $mask;
$mask +>= 1;
(}
$r *= $fraction;
 
return $r;
sub two-complement(Str $n where /^<[01]>+$/) {
(
(
$n
.trans("01" => "10")
.parse-base(2)
+ 1
) +& (2**$n.chars - 1)
).polymod(2 xx $n.chars - 1)
.reverse
.join
}
 
method Real {
return 0 unless @!bits.any;
return Inf if self ~~ /^10*$/;
my $sign = @!bits.head ?? -1 !! +1;
$sign *
grammar {
token TOP { ^ <regime> <exponent>? <fraction>? $ }
token regime { [ 1+ 0? ] | [ 0+ 1? ] }
token exponent { <.bit> ** {1..$es} }
token fraction { <.bit>+ }
token bit { <[01]> }
}.parse(
($sign > 0 ?? {$_} !! &two-complement)(self.Str.substr(1)),
actions => class {
method TOP($/) {
make $<regime>.made *
($<exponent> ?? $<exponent>.made !! 1) *
($<fraction> ?? $<fraction>.made !! 1);
}
method regime($/) {
my $first-bit = $/.Str.substr(0,1);
my $m = $/.comb.Bag{$first-bit};
make useed**($first-bit eq '1' ?? $m - 1 !! -$m);
}
method exponent($/) { make 2**($/.Str.parse-base: 2); }
method fraction($/) {
make reduce { $^a + $^b / ($*=2.FatRat) }, 1, |$/.comb;
}
}
)
.made
}
 
Line 71 ⟶ 60:
# example from L<http://www.johngustafson.net/pdfs/BeatingFloatingPoint.pdf>
is Posit[16, 3]
.new(bitsUInt => '0000110111011101'.comb.map({.Int.Bool}0b0000110111011101)).Real.nude,
(477.FatRat, 477.FatRat/134217728);
}</syntaxhighlight>
 
1,934

edits