Skip to content

Instantly share code, notes, and snippets.

@Ovid
Last active August 29, 2015 14:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Ovid/8dda7820aca6aec60124 to your computer and use it in GitHub Desktop.
Save Ovid/8dda7820aca6aec60124 to your computer and use it in GitHub Desktop.
# Rewriting this code (http://blogs.perl.org/users/ovid/2012/05/floating-point-rounding-errors.html)
# for Perl 6:
#!/usr/bin/env perl6
sub MAIN(Real $num where { 0 <= $_ < 1 }, Int :$bits = 32) {
my $accumulator = 0;
my $binary = '';
my @fractions;
for 1 .. $bits -> $bit {
my $denominator = 2 ** $bit;
my $fraction = 1 / $denominator;
if $accumulator + $fraction <= $num {
@fractions.push("1/$denominator");
$binary ~= 1;
$accumulator += $fraction;
}
else {
$binary ~= 0;
}
}
say qq:to"END";
Original: $num
Bits: $bits
Fractions: {@fractions.join(" + ")}
Binary: $binary
Result: $accumulator
END
}
=begin pod
If I run that with "./floating-point.p6 --bits=16 .3", I get the following:
Original: .3
Bits: 16
Fractions: 1/4 + 1/32 + 1/64 + 1/512 + 1/1024 + 1/8192 + 1/16384
Binary: 0100110011001100
Result: 0.299988
But if I run it with "./floating-point.p6 --bits=16 3" (note the `3` instead of `.3`), I get:
Usage:
./floating-point.p6 [--bits=<Int>] <num>
shell returned 2
That's interesting because 3 is a Real number, but Perl 6 doesn't like it here. Also, Perl 6
is saying it's an Int in the error message.
I can get it to work if I use Rat instead of Real.
As an aside, I also can't figure out how to add a constraint to `$bits` requiring it to be
greater than 0, but still keep my default. Perl 6 always tells me the syntax is wrong.
sub MAIN(Rat $num where { 0 <= $_ < 1 }, Int :$bits = 32 where { $_ > 0 } ) {
#===SORRY!=== Error while compiling ./accum.p6
#Missing block
#at ./floating-point.p6:3
#------> where { 0 <= $_ < 1 }, Int :$bits = 32 ⏏where { $_ > 0 } ) {
# expecting any of:
# postfix
# infix stopper
# infix or meta-infix
#
#shell returned 1
Or the following, which tells me I can't modify an immutable block if I pass it .3, but
gives me a usage error if I pass it 3:
sub MAIN(Rat $num where { 0 <= $_ < 1 }, Int :$bits where { $_ > 0 } = 32) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment