Categories
Posts in this category
- A shiny perl6.org site
- Creating an entry point for newcomers
- Sprixel, a 6 compiler powered by JavaScript
- Another perl6.org iteration
- Blackjack and Perl 6
- Why I commit Crud to the Perl 6 Test Suite
- Report from the Perl 6 Hackathon in Copenhagen
- Custom operators in Rakudo
- Defined Behaviour with Undefined Values
- Dissecting the "Starry obfu"
- Perl 6: Failing Softly with Unthrown Exceptions
- The first Perl 6 module on CPAN
- Google Summer of Code Mentor Recap
- Building a Huffman Tree With Rakudo
- Immutable Sigils and Context
- Is Perl 6 really Perl?
- Perl 6: Lost in Wonderland
- Lots of momentum in the Perl 6 community
- Musing and the future of feather and the Pugs repository
- Musings on Rakudo's spectest chart
- My first executable from Perl 6
- Trying to implement new operators - failed
- Let's build an object
- Perl 6 is optimized for fun
- How to get a parse tree for a Perl 6 Program
- Perl 6 in 2009
- Perl 6 ticket life cycle
- The Perl 6 Advent Calendar
- How to Plot a Segment of a Circle with SVG
- Publicity for Perl 6
- Rakudo architectural overview
- Rakudo Rocks
- Rakudo "star" announced
- Rakudo's rough edges
- Rats and other pets
- Releasing Rakudo made easy
- Set Phasers to Stun!
- Starry Perl 6 obfu
- Recent Perl 6 Developments August 2008
- Strings and Buffers
- Subroutines vs. Methods - Differences and Commonalities
- A SVG plotting adventure
- A Syntax Highlighter for Perl 6
- Test Suite Reorganization: How to move tests
- The Happiness of Design Convergence
- Perl 6 Tidings from September and October 2008
- Perl 6 Tidings for November 2008
- Perl 6 Tidings from December 2008
- Perl 6 Tidings from January 2009
- Perl 6 Tidings from February 2009
- Perl 6 Tidings from March 2009
- Perl 6 Tidings from April 2009
- Perl 6 Tidings from May 2009
- Perl 6 Tidings from May 2009 (second iteration)
- Perl 6 Tidings from June 2009
- Perl 6 Tidings from August 2009
- Perl 6 Tidings from October 2009
- Timeline for a syntax change in Perl 6
- Visualizing match trees
- We write a Perl 6 book for you
- When we reach 100% we did something wrong
- Where Rakudo Lives Now
- Why was the Perl 6 Advent Calendar such a Success?
- What you can write in Perl 6 today
- Why you don't need the Y combinator in Perl 6
Tue, 22 Sep 2009
Rats and other pets
Permanent link
If you follow perlmonks (or just about any other programming forum) you'll notice recurring questions related to floating point arithmetics not being accurate. A typical example would be
my $a = 1 / 10; my $b = 1; for ( 1..10 ) { $b -= $a; } if ( $b == 0 ) { print "yes\n"; } else { print "no\n"; } printf "%.20f\n", $b;
When you run this with perl5 the output is
no 0.00000000000000013878
And the reason is that 1/10 is an infinite binary fraction,
and perl uses floating points internally with only a finite number of bits for
the mantissa. So it subtracts ten times not exactly one tenth, but a number
close to that, and in the end the result is not exactly zero, but of the order
of magnitude of the machine precision.
However when you run the very same program with Perl 6, you get
yes 0.00000000000000000000
Why? Introspection helps:
$ perl6 -e 'say (1/10).WHAT' Rat() $ perl6 -e 'say (1/10).perl' 1/10
So 1/10 produces not a floating point number, but a
Rat object. Rat is short for Rational, and it's a fraction that
stores the numerator and denominator as an integer each, allowing exact
arithmetics without floating point errors.
Here is a real world example where this makes a difference:
These two plots are both made with SVG::Plot; the right hand
side uses floats, the left hand side uses Rats. With floats the zero axis
label is not exactly zero, but a small number close to zero. Instead of making
a special case for the zero label, or introducing complicated rounding rules,
I switched to Rats - which just implied changing a 5.0 (Num) to
5 (Int).
(Back in the days when I used pugs for Perl 6 programming I found the
extensive use of rationals quite annoying, because when I wanted to calculate
1/7 it would answer me with 1/7 - thank you, I knew
that already.
The current specification says that rationals should delegate string
representation to Num (aka floating point numbers), so say 1/7
produces 0.142857142857143. This is very handy, but means that
conversion to Str and back to a number loses precision. Works for me.)
(frettled gets credit for suggesting the title of this blog post).
Comments / Trackbacks:
Trackback URL:
/blog-en/perl-6/rats-and-other-pets.trackback
DarkoP wrote
'Rat' is a pretty ugly name. I think that today with code completion and similar stuff in text-editors, shorter names are no longer necessary, unless the original word is quite long.
SR wrote
Longer names are not shorter necessary
You honestly prefer the alternative?
use ReallyLongNames;
my Integer $i = 1;
my Integer $j = 10;
my Rational = $i/$j;
my CharacterString = "I got %stringsubsitution\n";
printf CharacterString, Rational;
SR wrote
Ack, I terribly mangled my comment. Darnit.
Moritz wrote
Long and short names
Despite common believe (or so it seems) not all programmers write their code in an IDE.
In fact I don't. I use vim, which has auto-completing features, but normally I don't bother using them, and I'd like it to stay that way.
The possibly of an IDE is no excuse for a badly huffmanized language (though one could ask how often you actually type Rat in Perl 6 - we don't have any data on that yet).
Write a comment
The comments on this blog post have been disabled; the comment form below will not work.