xref: /openbsd-src/gnu/usr.bin/perl/cpan/bignum/lib/bigfloat.pm (revision 5486feefcc8cb79b19e014ab332cc5dfd05b3b33)
1package bigfloat;
2
3use strict;
4use warnings;
5
6use Carp qw< carp croak >;
7
8our $VERSION = '0.67';
9
10use Exporter;
11our @ISA            = qw( Exporter );
12our @EXPORT_OK      = qw( PI e bpi bexp hex oct );
13our @EXPORT         = qw( inf NaN );
14
15use overload;
16
17my $obj_class = "Math::BigFloat";
18
19##############################################################################
20
21sub accuracy {
22    my $self = shift;
23    $obj_class -> accuracy(@_);
24}
25
26sub precision {
27    my $self = shift;
28    $obj_class -> precision(@_);
29}
30
31sub round_mode {
32    my $self = shift;
33    $obj_class -> round_mode(@_);
34}
35
36sub div_scale {
37    my $self = shift;
38    $obj_class -> div_scale(@_);
39}
40
41sub upgrade {
42    my $self = shift;
43    $obj_class -> upgrade(@_);
44}
45
46sub downgrade {
47    my $self = shift;
48    $obj_class -> downgrade(@_);
49}
50
51sub in_effect {
52    my $level = shift || 0;
53    my $hinthash = (caller($level))[10];
54    $hinthash->{bigfloat};
55}
56
57sub _float_constant {
58    my $str = shift;
59
60    # See if we can convert the input string to a string using a normalized form
61    # consisting of the significand as a signed integer, the character "e", and
62    # the exponent as a signed integer, e.g., "+0e+0", "+314e-2", and "-1e+3".
63
64    my $nstr;
65
66    if (
67        # See if it is an octal number. An octal number like '0377' is also
68        # accepted by the functions parsing decimal and hexadecimal numbers, so
69        # handle octal numbers before decimal and hexadecimal numbers.
70
71        $str =~ /^0(?:[Oo]|_*[0-7])/ and
72        $nstr = Math::BigInt -> oct_str_to_dec_flt_str($str)
73
74          or
75
76        # See if it is decimal number.
77
78        $nstr = Math::BigInt -> dec_str_to_dec_flt_str($str)
79
80          or
81
82        # See if it is a hexadecimal number. Every hexadecimal number has a
83        # prefix, but the functions parsing numbers don't require it, so check
84        # to see if it actually is a hexadecimal number.
85
86        $str =~ /^0[Xx]/ and
87        $nstr = Math::BigInt -> hex_str_to_dec_flt_str($str)
88
89          or
90
91        # See if it is a binary numbers. Every binary number has a prefix, but
92        # the functions parsing numbers don't require it, so check to see if it
93        # actually is a binary number.
94
95        $str =~ /^0[Bb]/ and
96        $nstr = Math::BigInt -> bin_str_to_dec_flt_str($str))
97    {
98        return $obj_class -> new($nstr);
99    }
100
101    # If we get here, there is a bug in the code above this point.
102
103    warn "Internal error: unable to handle literal constant '$str'.",
104      " This is a bug, so please report this to the module author.";
105    return $obj_class -> bnan();
106}
107
108#############################################################################
109# the following two routines are for "use bigfloat qw/hex oct/;":
110
111use constant LEXICAL => $] > 5.009004;
112
113# Internal function with the same semantics as CORE::hex(). This function is
114# not used directly, but rather by other front-end functions.
115
116sub _hex_core {
117    my $str = shift;
118
119    # Strip off, clean, and parse as much as we can from the beginning.
120
121    my $x;
122    if ($str =~ s/ ^ ( 0? [xX] )? ( [0-9a-fA-F]* ( _ [0-9a-fA-F]+ )* ) //x) {
123        my $chrs = $2;
124        $chrs =~ tr/_//d;
125        $chrs = '0' unless CORE::length $chrs;
126        $x = $obj_class -> from_hex($chrs);
127    } else {
128        $x = $obj_class -> bzero();
129    }
130
131    # Warn about trailing garbage.
132
133    if (CORE::length($str)) {
134        require Carp;
135        Carp::carp(sprintf("Illegal hexadecimal digit '%s' ignored",
136                           substr($str, 0, 1)));
137    }
138
139    return $x;
140}
141
142# Internal function with the same semantics as CORE::oct(). This function is
143# not used directly, but rather by other front-end functions.
144
145sub _oct_core {
146    my $str = shift;
147
148    $str =~ s/^\s*//;
149
150    # Hexadecimal input.
151
152    return _hex_core($str) if $str =~ /^0?[xX]/;
153
154    my $x;
155
156    # Binary input.
157
158    if ($str =~ /^0?[bB]/) {
159
160        # Strip off, clean, and parse as much as we can from the beginning.
161
162        if ($str =~ s/ ^ ( 0? [bB] )? ( [01]* ( _ [01]+ )* ) //x) {
163            my $chrs = $2;
164            $chrs =~ tr/_//d;
165            $chrs = '0' unless CORE::length $chrs;
166            $x = $obj_class -> from_bin($chrs);
167        }
168
169        # Warn about trailing garbage.
170
171        if (CORE::length($str)) {
172            require Carp;
173            Carp::carp(sprintf("Illegal binary digit '%s' ignored",
174                               substr($str, 0, 1)));
175        }
176
177        return $x;
178    }
179
180    # Octal input. Strip off, clean, and parse as much as we can from the
181    # beginning.
182
183    if ($str =~ s/ ^ ( 0? [oO] )? ( [0-7]* ( _ [0-7]+ )* ) //x) {
184        my $chrs = $2;
185        $chrs =~ tr/_//d;
186        $chrs = '0' unless CORE::length $chrs;
187        $x = $obj_class -> from_oct($chrs);
188    }
189
190    # Warn about trailing garbage. CORE::oct() only warns about 8 and 9, but it
191    # is more helpful to warn about all invalid digits.
192
193    if (CORE::length($str)) {
194        require Carp;
195        Carp::carp(sprintf("Illegal octal digit '%s' ignored",
196                           substr($str, 0, 1)));
197    }
198
199    return $x;
200}
201
202{
203    my $proto = LEXICAL ? '_' : ';$';
204    eval '
205sub hex(' . $proto . ') {' . <<'.';
206    my $str = @_ ? $_[0] : $_;
207    _hex_core($str);
208}
209.
210
211    eval '
212sub oct(' . $proto . ') {' . <<'.';
213    my $str = @_ ? $_[0] : $_;
214    _oct_core($str);
215}
216.
217}
218
219#############################################################################
220# the following two routines are for Perl 5.9.4 or later and are lexical
221
222my ($prev_oct, $prev_hex, $overridden);
223
224if (LEXICAL) { eval <<'.' }
225sub _hex(_) {
226    my $hh = (caller 0)[10];
227    return $$hh{bigfloat} ? bigfloat::_hex_core($_[0])
228         : $$hh{bigrat} ? bigrat::_hex_core($_[0])
229         : $$hh{bigint} ? bigint::_hex_core($_[0])
230         : $prev_hex    ? &$prev_hex($_[0])
231         : CORE::hex($_[0]);
232}
233
234sub _oct(_) {
235    my $hh = (caller 0)[10];
236    return $$hh{bigfloat} ? bigfloat::_oct_core($_[0])
237         : $$hh{bigrat} ? bigrat::_oct_core($_[0])
238         : $$hh{bigint} ? bigint::_oct_core($_[0])
239         : $prev_oct    ? &$prev_oct($_[0])
240         : CORE::oct($_[0]);
241}
242.
243
244sub _override {
245    return if $overridden;
246    $prev_oct = *CORE::GLOBAL::oct{CODE};
247    $prev_hex = *CORE::GLOBAL::hex{CODE};
248    no warnings 'redefine';
249    *CORE::GLOBAL::oct = \&_oct;
250    *CORE::GLOBAL::hex = \&_hex;
251    $overridden = 1;
252}
253
254sub unimport {
255    delete $^H{bigfloat};       # no longer in effect
256    overload::remove_constant('binary', '', 'float', '', 'integer');
257}
258
259sub import {
260    my $class = shift;
261
262    $^H{bigfloat} = 1;          # we are in effect
263    delete $^H{bigint};
264    delete $^H{bigrat};
265
266    # for newer Perls always override hex() and oct() with a lexical version:
267    if (LEXICAL) {
268        _override();
269    }
270
271    my @import = ();
272    my @a = ();                         # unrecognized arguments
273    my $ver;                            # version?
274
275    while (@_) {
276        my $param = shift;
277
278        # Accuracy.
279
280        if ($param =~ /^a(ccuracy)?$/) {
281            push @import, 'accuracy', shift();
282            next;
283        }
284
285        # Precision.
286
287        if ($param =~ /^p(recision)?$/) {
288            push @import, 'precision', shift();
289            next;
290        }
291
292        # Rounding mode.
293
294        if ($param eq 'round_mode') {
295            push @import, 'round_mode', shift();
296            next;
297        }
298
299        # Backend library.
300
301        if ($param =~ /^(l|lib|try|only)$/) {
302            push @import, $param eq 'l' ? 'lib' : $param;
303            push @import, shift() if @_;
304            next;
305        }
306
307        if ($param =~ /^(v|version)$/) {
308            $ver = 1;
309            next;
310        }
311
312        if ($param =~ /^(t|trace)$/) {
313            $obj_class .= "::Trace";
314            eval "require $obj_class";
315            die $@ if $@;
316            next;
317        }
318
319        if ($param =~ /^(PI|e|bexp|bpi|hex|oct)\z/) {
320            push @a, $param;
321            next;
322        }
323
324        croak("Unknown option '$param'");
325    }
326
327    eval "require $obj_class";
328    die $@ if $@;
329    $obj_class -> import(@import);
330
331    if ($ver) {
332        printf "%-31s v%s\n", $class, $class -> VERSION();
333        printf " lib => %-23s v%s\n",
334          $obj_class -> config("lib"), $obj_class -> config("lib_version");
335        printf "%-31s v%s\n", $obj_class, $obj_class -> VERSION();
336        exit;
337    }
338
339    $class -> export_to_level(1, $class, @a);   # export inf, NaN, etc.
340
341    overload::constant
342
343        # This takes care each number written as decimal integer and within the
344        # range of what perl can represent as an integer, e.g., "314", but not
345        # "3141592653589793238462643383279502884197169399375105820974944592307".
346
347        integer => sub {
348            #printf "Value '%s' handled by the 'integer' sub.\n", $_[0];
349            my $str = shift;
350            return $obj_class -> new($str);
351        },
352
353        # This takes care of each number written with a decimal point and/or
354        # using floating point notation, e.g., "3.", "3.0", "3.14e+2" (decimal),
355        # "0b1.101p+2" (binary), "03.14p+2" and "0o3.14p+2" (octal), and
356        # "0x3.14p+2" (hexadecimal).
357
358        float => sub {
359            #printf "# Value '%s' handled by the 'float' sub.\n", $_[0];
360            _float_constant(shift);
361        },
362
363        # Take care of each number written as an integer (no decimal point or
364        # exponent) using binary, octal, or hexadecimal notation, e.g., "0b101"
365        # (binary), "0314" and "0o314" (octal), and "0x314" (hexadecimal).
366
367        binary => sub {
368            #printf "# Value '%s' handled by the 'binary' sub.\n", $_[0];
369            my $str = shift;
370            return $obj_class -> new($str) if $str =~ /^0[XxBb]/;
371            $obj_class -> from_oct($str);
372        };
373}
374
375sub inf () { $obj_class -> binf(); }
376sub NaN () { $obj_class -> bnan(); }
377
378# This should depend on the current accuracy/precision. Fixme!
379sub PI  () { $obj_class -> new('3.141592653589793238462643383279502884197'); }
380sub e   () { $obj_class -> new('2.718281828459045235360287471352662497757'); }
381
382sub bpi ($) {
383    my $up = Math::BigFloat -> upgrade();   # get current upgrading, if any ...
384    Math::BigFloat -> upgrade(undef);       # ... and disable
385
386    my $x = Math::BigFloat -> bpi(@_);
387
388    Math::BigFloat -> upgrade($up);         # reset the upgrading
389
390    return $x;
391}
392
393sub bexp ($$) {
394    my $up = Math::BigFloat -> upgrade();   # get current upgrading, if any ...
395    Math::BigFloat -> upgrade(undef);       # ... and disable
396
397    my $x = Math::BigFloat -> new(shift);
398    $x -> bexp(@_);
399
400    Math::BigFloat -> upgrade($up);         # reset the upgrading
401
402    return $x;
403}
404
4051;
406
407__END__
408
409=pod
410
411=head1 NAME
412
413bigfloat - transparent big floating point number support for Perl
414
415=head1 SYNOPSIS
416
417    use bigfloat;
418
419    $x = 2 + 4.5;                       # Math::BigFloat 6.5
420    print 2 ** 512 * 0.1;               # Math::BigFloat 134...09.6
421    print inf + 42;                     # Math::BigFloat inf
422    print NaN * 7;                      # Math::BigFloat NaN
423    print hex("0x1234567890123490");    # Perl v5.10.0 or later
424
425    {
426        no bigfloat;
427        print 2 ** 256;                 # a normal Perl scalar now
428    }
429
430    # for older Perls, import into current package:
431    use bigfloat qw/hex oct/;
432    print hex("0x1234567890123490");
433    print oct("01234567890123490");
434
435=head1 DESCRIPTION
436
437All numeric literals in the given scope are converted to Math::BigFloat objects.
438
439All operators (including basic math operations) except the range operator C<..>
440are overloaded.
441
442So, the following:
443
444    use bigfloat;
445    $x = 1234;
446
447creates a Math::BigFloat and stores a reference to in $x. This happens
448transparently and behind your back, so to speak.
449
450You can see this with the following:
451
452    perl -Mbigfloat -le 'print ref(1234)'
453
454Since numbers are actually objects, you can call all the usual methods from
455Math::BigFloat on them. This even works to some extent on expressions:
456
457    perl -Mbigfloat -le '$x = 1234; print $x->bdec()'
458    perl -Mbigfloat -le 'print 1234->copy()->binc();'
459    perl -Mbigfloat -le 'print 1234->copy()->binc->badd(6);'
460    perl -Mbigfloat -le 'print +(1234)->copy()->binc()'
461
462(Note that print doesn't do what you expect if the expression starts with
463'(' hence the C<+>)
464
465You can even chain the operations together as usual:
466
467    perl -Mbigfloat -le 'print 1234->copy()->binc->badd(6);'
468    1241
469
470Please note the following does not work as expected (prints nothing), since
471overloading of '..' is not yet possible in Perl (as of v5.8.0):
472
473    perl -Mbigfloat -le 'for (1..2) { print ref($_); }'
474
475=head2 Options
476
477C<bigfloat> recognizes some options that can be passed while loading it via via
478C<use>. The following options exist:
479
480=over 4
481
482=item a or accuracy
483
484This sets the accuracy for all math operations. The argument must be greater
485than or equal to zero. See Math::BigInt's bround() method for details.
486
487    perl -Mbigfloat=a,50 -le 'print sqrt(20)'
488
489Note that setting precision and accuracy at the same time is not possible.
490
491=item p or precision
492
493This sets the precision for all math operations. The argument can be any
494integer. Negative values mean a fixed number of digits after the dot, while a
495positive value rounds to this digit left from the dot. 0 means round to integer.
496See Math::BigInt's bfround() method for details.
497
498    perl -Mbigfloat=p,-50 -le 'print sqrt(20)'
499
500Note that setting precision and accuracy at the same time is not possible.
501
502=item t or trace
503
504This enables a trace mode and is primarily for debugging.
505
506=item l, lib, try, or only
507
508Load a different math lib, see L<Math Library>.
509
510    perl -Mbigfloat=l,GMP -e 'print 2 ** 512'
511    perl -Mbigfloat=lib,GMP -e 'print 2 ** 512'
512    perl -Mbigfloat=try,GMP -e 'print 2 ** 512'
513    perl -Mbigfloat=only,GMP -e 'print 2 ** 512'
514
515=item hex
516
517Override the built-in hex() method with a version that can handle big numbers.
518This overrides it by exporting it to the current package. Under Perl v5.10.0 and
519higher, this is not so necessary, as hex() is lexically overridden in the
520current scope whenever the C<bigfloat> pragma is active.
521
522=item oct
523
524Override the built-in oct() method with a version that can handle big numbers.
525This overrides it by exporting it to the current package. Under Perl v5.10.0 and
526higher, this is not so necessary, as oct() is lexically overridden in the
527current scope whenever the C<bigfloat> pragma is active.
528
529=item v or version
530
531this prints out the name and version of the modules and then exits.
532
533    perl -Mbigfloat=v
534
535=back
536
537=head2 Math Library
538
539Math with the numbers is done (by default) by a backend library module called
540Math::BigInt::Calc. The default is equivalent to saying:
541
542    use bigfloat lib => 'Calc';
543
544you can change this by using:
545
546    use bigfloat lib => 'GMP';
547
548The following would first try to find Math::BigInt::Foo, then Math::BigInt::Bar,
549and if this also fails, revert to Math::BigInt::Calc:
550
551    use bigfloat lib => 'Foo,Math::BigInt::Bar';
552
553Using c<lib> warns if none of the specified libraries can be found and
554L<Math::BigInt> fell back to one of the default libraries. To suppress this
555warning, use c<try> instead:
556
557    use bigfloat try => 'GMP';
558
559If you want the code to die instead of falling back, use C<only> instead:
560
561    use bigfloat only => 'GMP';
562
563Please see respective module documentation for further details.
564
565=head2 Method calls
566
567Since all numbers are now objects, you can use all methods that are part of the
568Math::BigFloat API.
569
570But a warning is in order. When using the following to make a copy of a number,
571only a shallow copy will be made.
572
573    $x = 9; $y = $x;
574    $x = $y = 7;
575
576Using the copy or the original with overloaded math is okay, e.g., the following
577work:
578
579    $x = 9; $y = $x;
580    print $x + 1, " ", $y,"\n";     # prints 10 9
581
582but calling any method that modifies the number directly will result in B<both>
583the original and the copy being destroyed:
584
585    $x = 9; $y = $x;
586    print $x->badd(1), " ", $y,"\n";        # prints 10 10
587
588    $x = 9; $y = $x;
589    print $x->binc(1), " ", $y,"\n";        # prints 10 10
590
591    $x = 9; $y = $x;
592    print $x->bmul(2), " ", $y,"\n";        # prints 18 18
593
594Using methods that do not modify, but test that the contents works:
595
596    $x = 9; $y = $x;
597    $z = 9 if $x->is_zero();                # works fine
598
599See the documentation about the copy constructor and C<=> in overload, as well
600as the documentation in Math::BigFloat for further details.
601
602=head2 Methods
603
604=over 4
605
606=item inf()
607
608A shortcut to return Math::BigFloat->binf(). Useful because Perl does not always
609handle bareword C<inf> properly.
610
611=item NaN()
612
613A shortcut to return Math::BigFloat->bnan(). Useful because Perl does not always
614handle bareword C<NaN> properly.
615
616=item e
617
618    # perl -Mbigfloat=e -wle 'print e'
619
620Returns Euler's number C<e>, aka exp(1)
621
622=item PI
623
624    # perl -Mbigfloat=PI -wle 'print PI'
625
626Returns PI.
627
628=item bexp()
629
630    bexp($power, $accuracy);
631
632Returns Euler's number C<e> raised to the appropriate power, to the wanted
633accuracy.
634
635Example:
636
637    # perl -Mbigfloat=bexp -wle 'print bexp(1,80)'
638
639=item bpi()
640
641    bpi($accuracy);
642
643Returns PI to the wanted accuracy.
644
645Example:
646
647    # perl -Mbigfloat=bpi -wle 'print bpi(80)'
648
649=item accuracy()
650
651Set or get the accuracy.
652
653=item precision()
654
655Set or get the precision.
656
657=item round_mode()
658
659Set or get the rounding mode.
660
661=item div_scale()
662
663Set or get the division scale.
664
665=item upgrade()
666
667Set or get the class that the downgrade class upgrades to, if any. Set the
668upgrade class to C<undef> to disable upgrading.
669
670Upgrading is disabled by default.
671
672=item downgrade()
673
674Set or get the class that the upgrade class downgrades to, if any. Set the
675downgrade class to C<undef> to disable upgrading.
676
677Downgrading is disabled by default.
678
679=item in_effect()
680
681    use bigfloat;
682
683    print "in effect\n" if bigfloat::in_effect;       # true
684    {
685        no bigfloat;
686        print "in effect\n" if bigfloat::in_effect;   # false
687    }
688
689Returns true or false if C<bigfloat> is in effect in the current scope.
690
691This method only works on Perl v5.9.4 or later.
692
693=back
694
695=head1 CAVEATS
696
697=over 4
698
699=item Hexadecimal, octal, and binary floating point literals
700
701Perl (and this module) accepts hexadecimal, octal, and binary floating point
702literals, but use them with care with Perl versions before v5.32.0, because some
703versions of Perl silently give the wrong result.
704
705=item Operator vs literal overloading
706
707C<bigrat> works by overloading handling of integer and floating point literals,
708converting them to L<Math::BigRat> objects.
709
710This means that arithmetic involving only string values or string literals are
711performed using Perl's built-in operators.
712
713For example:
714
715    use bigrat;
716    my $x = "900000000000000009";
717    my $y = "900000000000000007";
718    print $x - $y;
719
720outputs C<0> on default 32-bit builds, since C<bigfloat> never sees the string
721literals. To ensure the expression is all treated as C<Math::BigFloat> objects,
722use a literal number in the expression:
723
724    print +(0+$x) - $y;
725
726=item Ranges
727
728Perl does not allow overloading of ranges, so you can neither safely use ranges
729with C<bigfloat> endpoints, nor is the iterator variable a C<Math::BigFloat>.
730
731    use 5.010;
732    for my $i (12..13) {
733      for my $j (20..21) {
734        say $i ** $j;  # produces a floating-point number,
735                       # not an object
736      }
737    }
738
739=item in_effect()
740
741This method only works on Perl v5.9.4 or later.
742
743=item hex()/oct()
744
745C<bigfloat> overrides these routines with versions that can also handle big
746integer values. Under Perl prior to version v5.9.4, however, this will not
747happen unless you specifically ask for it with the two import tags "hex" and
748"oct" - and then it will be global and cannot be disabled inside a scope with
749C<no bigfloat>:
750
751    use bigfloat qw/hex oct/;
752
753    print hex("0x1234567890123456");
754    {
755        no bigfloat;
756        print hex("0x1234567890123456");
757    }
758
759The second call to hex() will warn about a non-portable constant.
760
761Compare this to:
762
763    use bigfloat;
764
765    # will warn only under Perl older than v5.9.4
766    print hex("0x1234567890123456");
767
768=back
769
770=head1 EXAMPLES
771
772Some cool command line examples to impress the Python crowd ;)
773
774    perl -Mbigfloat -le 'print sqrt(33)'
775    perl -Mbigfloat -le 'print 2**255'
776    perl -Mbigfloat -le 'print 4.5+2**255'
777    perl -Mbigfloat -le 'print 3/7 + 5/7 + 8/3'
778    perl -Mbigfloat -le 'print 123->is_odd()'
779    perl -Mbigfloat -le 'print log(2)'
780    perl -Mbigfloat -le 'print exp(1)'
781    perl -Mbigfloat -le 'print 2 ** 0.5'
782    perl -Mbigfloat=a,65 -le 'print 2 ** 0.2'
783    perl -Mbigfloat=l,GMP -le 'print 7 ** 7777'
784
785=head1 BUGS
786
787Please report any bugs or feature requests to
788C<bug-bignum at rt.cpan.org>, or through the web interface at
789L<https://rt.cpan.org/Ticket/Create.html?Queue=bignum> (requires login).
790We will be notified, and then you'll automatically be notified of
791progress on your bug as I make changes.
792
793=head1 SUPPORT
794
795You can find documentation for this module with the perldoc command.
796
797    perldoc bigfloat
798
799You can also look for information at:
800
801=over 4
802
803=item * GitHub
804
805L<https://github.com/pjacklam/p5-bignum>
806
807=item * RT: CPAN's request tracker
808
809L<https://rt.cpan.org/Dist/Display.html?Name=bignum>
810
811=item * MetaCPAN
812
813L<https://metacpan.org/release/bignum>
814
815=item * CPAN Testers Matrix
816
817L<http://matrix.cpantesters.org/?dist=bignum>
818
819=back
820
821=head1 LICENSE
822
823This program is free software; you may redistribute it and/or modify it under
824the same terms as Perl itself.
825
826=head1 SEE ALSO
827
828L<bigint> and L<bigrat>.
829
830L<Math::BigInt>, L<Math::BigFloat>, L<Math::BigRat> and L<Math::Big> as well as
831L<Math::BigInt::FastCalc>, L<Math::BigInt::Pari> and L<Math::BigInt::GMP>.
832
833=head1 AUTHORS
834
835=over 4
836
837=item *
838
839(C) by Tels L<http://bloodgate.com/> in early 2002 - 2007.
840
841=item *
842
843Maintained by Peter John Acklam E<lt>pjacklam@gmail.comE<gt>, 2014-.
844
845=back
846
847=cut
848