-
-
Save Ovid/8dda7820aca6aec60124 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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