```On Mon, 06 Oct 2008 at wee small hour of 02:20:22 EDT
you, Michael G Schwern <[EMAIL PROTECTED]>, wrote:```
```
> Darren Duncan wrote:

>>> [2] "Num" should have an optional limit on the number of
>>>     decimal places it remembers, like NUMERIC in SQL, but
>>>     that's a simple truncation.

>> I disagree.

>> Any numeric operations that would return an irrational number
>> in the general case, such as sqrt() and sin(), and the user
>> desires the result to be truncated to an exact rational number
>> rather than as a symbolic number, then those operators should
>> have an extra argument that specifies rounding, eg to an exact
>> multiple of 1/1000.

> That seems like scattering a lot of redundant extra arguments
> around.  The nice thing about doing it as part of the type is
> you just specify it once.

> But instead of truncating data in the type, maybe what I want
> is to leave the full accuracy inside and instead override
> string/numification to display only 2 decimal places.

This is currently something of an annoyance with Math::Complex.
It needs a way of specify epsilon.

If you ask for both sqrt()s of 4, you get

(2, -2+2.44929359829471e-16i)

in Cartesian but in Polar:

( [2,0], [2,pi] )

Is the problem that it's working in Polar and the conversion to
Cartesian is off by a wee bit?  I would really like to get
Cartesian answers of (2, -2), not that -2e-16i silliness.

If you ask for both roots of -4, you get

Cartesian:
( 1.22464679914735e-16+2i, -3.67394039744206e-16-2i )
Polar:
( [2,pi/2], [2,-1pi/2] );

But I'd like a Cartesian return of (2i, -2i).
And a Polar return of ([2,pi/2],[2,-pi/2]).

It's worse still with the 10 roots of 2**10:

The 10 roots of 1024 are:
CRTSN:  1: 2
POLAR:  1: [2,0]
CRTSN:  2: 1.61803398874989+1.17557050458495i
POLAR:  2: [2,pi/5]
CRTSN:  3: 0.618033988749895+1.90211303259031i
POLAR:  3: [2,2pi/5]
CRTSN:  4: -0.618033988749895+1.90211303259031i
POLAR:  4: [2,3pi/5]
CRTSN:  5: -1.61803398874989+1.17557050458495i
POLAR:  5: [2,4pi/5]
CRTSN:  6: -2+2.44929359829471e-16i
POLAR:  6: [2,pi]
CRTSN:  7: -1.61803398874989-1.17557050458495i
POLAR:  7: [2,-4pi/5]
CRTSN:  8: -0.618033988749895-1.90211303259031i
POLAR:  8: [2,-3pi/5]
CRTSN:  9: 0.618033988749894-1.90211303259031i
POLAR:  9: [2,-2pi/5]
CRTSN: 10: 1.61803398874989-1.17557050458495i
POLAR: 10: [2,-1pi/5]

The 10 roots of -1024 are:
CRTSN:  1: 1.90211303259031+0.618033988749895i
POLAR:  1: [2,0.314159265358979]
CRTSN:  2: 1.17557050458495+1.61803398874989i
POLAR:  2: [2,0.942477796076938]
CRTSN:  3: 1.22464679914735e-16+2i
POLAR:  3: [2,pi/2]
CRTSN:  4: -1.17557050458495+1.61803398874989i
POLAR:  4: [2,2.19911485751286]
CRTSN:  5: -1.90211303259031+0.618033988749895i
POLAR:  5: [2,2.82743338823081]
CRTSN:  6: -1.90211303259031-0.618033988749895i
POLAR:  6: [2,-2.82743338823081]
CRTSN:  7: -1.17557050458495-1.61803398874989i
POLAR:  7: [2,-2.19911485751286]
CRTSN:  8: -3.67394039744206e-16-2i
POLAR:  8: [2,-1pi/2]
CRTSN:  9: 1.17557050458495-1.6180339887499i
POLAR:  9: [2,-0.942477796076938]
CRTSN: 10: 1.90211303259031-0.618033988749895i
POLAR: 10: [2,-0.31415926535898]

>> Note, a generic numeric rounding operator would also take the
>> "exact multiple of" argument rather than a "number of digits"
>> argument, except when that operator is simply rounding to an
>> integer, in which case no such argument is applicable.

>> Note, for extra determinism and flexibility, any operation
>> rounding/truncating to a rational would also take an optional
>> argument specifying the rounding method, eg so users can
>> choose between the likes of half-up, to-even, to-zero, etc.
>> Then Perl can easily copy any semantics a user desires,
>> including when code is ported from other languages and wants
>> to maintain exact semantics.

> Yes, this is very important for currency operations.

>> Now, as I see it, if "Num" has any purpose apart from "Rat",
>> it would be like a "whatever" numeric type or effectively a
>> union of the Int|Rat|that-symbolic-number-type|etc types, for
>> people that just want to accept numbers from somewhere and
>> don't care about the exact semantics.  The actual underlying
>> type used in any given situation would determine the exact
>> semantics.  So Int and Rat would be exact and unlimited
>> precision, and maybe Symbolic or IRat or something would be
>> the symbolic number type, also with exact precision
>> components.

> That sounds right.  It's the "whatever can conceivably be
> called a number" type.

I think you might be surprised by what some people conceive
of by numbers. :-(

--tom

#!/usr/bin/perl

use strict;
use warnings;

use Math::Complex;

my \$STYLE = "NORMAL";
# my \$STYLE = "HACKED";

unless (@ARGV) {
die "usage: \$0 number rootcount\n";
}

my (\$number, \$rootcount) = @ARGV;

\$number = cplx(\$number);

die "\$0: \$number poor for rooting\n" if !\$number;
die "\$0: \$rootcount should be positive integer"
if \$rootcount && int(\$rootcount) != \$rootcount;

print "The \$rootcount roots of \$number are:\n";

my @roots = root(\$number, int(\$rootcount));
my \$width = length @roots;

for (my \$idx = 0; \$idx < @roots; \$idx++) {
my \$z = \$roots[\$idx];
my \$r = Re(\$z);
my \$i = Im(\$z);

if (\$STYLE eq "NORMAL") {
printf "CRTSN: %\${width}d: %s\n", 1+\$idx, \$z;
\$z->display_format("polar");
printf "POLAR: %\${width}d: %s\n", 1+\$idx, \$z;
next;
}

printf "%\${width}d: ", 1+\$idx;

if (\$r) {
my \$s = sprintf "%.6f", \$r;
\$s =~ s/0+\$//;

if (\$s =~ s/\.\$//) {
# whole RE part
print ((\$s < 0) ? "-" : " ");
printf "%-7d", abs(\$s);
} else {
printf "%8g", \$s;
}

} else {
}
if (\$i) {
my \$s = sprintf "%.6f", \$i;
\$s =~ s/0+\$//;
\$s =~ s/\.\$//;

if (\$s ne '0') {
print " " if \$s !~ m/\./;
print ((\$s < 0) ? " -" : "+" );

if (\$s !~ m/\./) {
printf "%di", abs(\$s);
} else {
printf "%7gi", abs(\$s);
}
}

}

print "\n\n";

}

```