Re: r29111 - docs/Perl6/Spec

2009-11-19 Thread Darren Duncan

Darren Duncan wrote:

Moritz Lenz wrote:

FatRat.new(45207196, 10**37);

And note that a decimal-specific answer isn't what I want, since I 
want  something that would also work for this:


  45207196 * 11 ** -37


FatRat.new(45207196, 11**37);


Solomon Foster wrote:

What's your objection to FatRat.new(45207196, 11 ** 37)?


Well, for one thing, that's not the same value.  I had a -37 as the 
exponent, designating a small non-integer rational value, whereas the 
FatRat example had flipped this around to 37, not the same value.


Now I'm sure the format you showed looks great, but my concern is, does 
simply saying this:


  11 ** -37

... result in a FatRat and if not then how do I write 11^-37 in Perl 6 
such that the resulting object retains the full precision of the value?


Actually, I realize now what was going on with that suggestion, and that it 
actually was valid for the case I mentioned, being presumably equal to:


  45207196 * FatRat.new( 1, 11**37 )

However, the ideal situation would be a format I could use unchanged regardless 
of whether the exponent (-37) is positive or negative.


Unless there is one, it would seem I might have to do this in a generic setting, 
given 3 integers $mantis, $radix, $exp but $radix is always = 2:


  $exp  0 ?? FatRat.new( $mantis, $radix**$exp ) !! $mantis * $radix**$exp

What I think might be ideal though is if the FatRat.new() could be a multi that 
also has a 3-param variant, so that something like this would work:


  FatRat.new( $mantissa, $radix, $exponent )

I would be clear that this 3-param variant would be 3 integers, including the 
mantissa, because that guarantees that the new FatRat would be an exact multiple 
of $radix**$exponent.


-- Darren Duncan


Re: r29111 - docs/Perl6/Spec

2009-11-18 Thread Darren Duncan

Acknowledging that 'FatRat' is current name for above 'Ratio' ...

pugs-comm...@feather.perl6.nl wrote:

-For applications that really need arbitrary precision denominators
-as well as numerators, CRatio may be used, which is defined as CInt/Int.
+For applications that really need arbitrary precision denominators as
+well as numerators at the cost of performance, CRatio may be used,
+which is stored as CInt/Int, that is, as arbitrary precision in
+both parts.  There is no literal form for a CRatio, so it must
+be constructed using CRatio.new($nu,$de).  In general, only math
+operators with at least one CRatio argument will return another
+CRatio, to prevent accidental promotion of reasonably fast CRat
+values into arbitrarily slow CRatio values.


Given the above, if one wants to construct a full-precision rational value in 
terms of 3 Int values analogous to a mantissa and radix and exponent, what is 
the best way to write it in Perl 6?


For example, say I want the following expression to result in a FatRat because 
presumably that's the only type which will represent the result value exactly:


  45207196 * 10 ** -37

How should that be spelled out in terms of 3 integers?

And note that a decimal-specific answer isn't what I want, since I want 
something that would also work for this:


  45207196 * 11 ** -37

Any thoughts?

Basically where I'm coming from here is the idea that any rational can also be 
expressed as 3 integers like the above, not just the numerator/denominator pair; 
the 3 integers are advantages both for being efficient with common pathological 
cases such as very large or very small rationals with a small amount of 
precision, such as the above, as well as for exactly reflecting the concept of a 
radix-agnostic floating-point number.


Thank you. -- Darren Duncan



Re: r29111 - docs/Perl6/Spec

2009-11-18 Thread Solomon Foster
On Wed, Nov 18, 2009 at 3:33 AM, Darren Duncan dar...@darrenduncan.net wrote:
 Acknowledging that 'FatRat' is current name for above 'Ratio' ...

 pugs-comm...@feather.perl6.nl wrote:

 -For applications that really need arbitrary precision denominators
 -as well as numerators, CRatio may be used, which is defined as
 CInt/Int.
 +For applications that really need arbitrary precision denominators as
 +well as numerators at the cost of performance, CRatio may be used,
 +which is stored as CInt/Int, that is, as arbitrary precision in
 +both parts.  There is no literal form for a CRatio, so it must
 +be constructed using CRatio.new($nu,$de).  In general, only math
 +operators with at least one CRatio argument will return another
 +CRatio, to prevent accidental promotion of reasonably fast CRat
 +values into arbitrarily slow CRatio values.

 Given the above, if one wants to construct a full-precision rational value
 in terms of 3 Int values analogous to a mantissa and radix and exponent,
 what is the best way to write it in Perl 6?

 For example, say I want the following expression to result in a FatRat
 because presumably that's the only type which will represent the result
 value exactly:

  45207196 * 10 ** -37

 How should that be spelled out in terms of 3 integers?

 And note that a decimal-specific answer isn't what I want, since I want
 something that would also work for this:

  45207196 * 11 ** -37

 Any thoughts?

 Basically where I'm coming from here is the idea that any rational can also
 be expressed as 3 integers like the above, not just the
 numerator/denominator pair; the 3 integers are advantages both for being
 efficient with common pathological cases such as very large or very small
 rationals with a small amount of precision, such as the above, as well as
 for exactly reflecting the concept of a radix-agnostic floating-point
 number.

What's your objection to FatRat.new(45207196, 11 ** 37)?

-- 
Solomon Foster: colo...@gmail.com
HarmonyWare, Inc: http://www.harmonyware.com


Re: r29111 - docs/Perl6/Spec

2009-11-18 Thread Moritz Lenz
On Wed, Nov 18, 2009 at 12:33:35AM -0800, Darren Duncan wrote:
 Acknowledging that 'FatRat' is current name for above 'Ratio' ...

 pugs-comm...@feather.perl6.nl wrote:
 -For applications that really need arbitrary precision denominators
 -as well as numerators, CRatio may be used, which is defined as CInt/Int.
 +For applications that really need arbitrary precision denominators as
 +well as numerators at the cost of performance, CRatio may be used,
 +which is stored as CInt/Int, that is, as arbitrary precision in
 +both parts.  There is no literal form for a CRatio, so it must
 +be constructed using CRatio.new($nu,$de).  In general, only math
 +operators with at least one CRatio argument will return another
 +CRatio, to prevent accidental promotion of reasonably fast CRat
 +values into arbitrarily slow CRatio values.

 Given the above, if one wants to construct a full-precision rational 
 value in terms of 3 Int values analogous to a mantissa and radix and 
 exponent, what is the best way to write it in Perl 6?

 For example, say I want the following expression to result in a FatRat 
 because presumably that's the only type which will represent the result 
 value exactly:

   45207196 * 10 ** -37

 How should that be spelled out in terms of 3 integers?

why 3?

FatRat.new(45207196, 10**37);

 And note that a decimal-specific answer isn't what I want, since I want  
 something that would also work for this:

   45207196 * 11 ** -37

FatRat.new(45207196, 11**37);

 Any thoughts?

 Basically where I'm coming from here is the idea that any rational can 
 also be expressed as 3 integers like the above, not just the 
 numerator/denominator pair; the 3 integers are advantages both for being 
 efficient with common pathological cases such as very large or very small 
 rationals with a small amount of precision, such as the above, as well as 
 for exactly reflecting the concept of a radix-agnostic floating-point 
 number.

I think that's an implementation detail. If you care much about it, you'll
have to provide your Rat type.

Cheers,
Moritz


Re: r29111 - docs/Perl6/Spec

2009-11-18 Thread Jon Lang
Moritz Lenz wrote:
 Given the above, if one wants to construct a full-precision rational
 value in terms of 3 Int values analogous to a mantissa and radix and
 exponent, what is the best way to write it in Perl 6?

 For example, say I want the following expression to result in a FatRat
 because presumably that's the only type which will represent the result
 value exactly:

   45207196 * 10 ** -37

 How should that be spelled out in terms of 3 integers?

 why 3?

Because three attributes let you define them all as the same kind of
int, instead of one having twice as many bits in it as the other:

has int128 $whole, int128 $numerator, int128 $denominator

vs.

has int256 $numerator, int128 $denominator

This matters when you reach the upper end of the low-level integer
types, such that there is no longer an available integer type that has
twice as many bits as the denominator type.  But as you say, this is
an implementation detail.  The important thing for the Spec to note is
that user expectations require Rational types to be able to handle a
whole number part that's at least as large as the denominator part.
Right now, the spec is addressing this in terms of implementation
details: it assumes that a Rational will store exactly two numbers,
representing the numerator and the denominator, and that the numerator
must have twice as much storage space reserved for it as the
denominator has.  Why twice as much?  So that no matter how large the
denominator is, the numerator will be large enough to store a whole
number part that's at least as large.  The doubled bits isn't an end
to itself, but merely a means to a more fundamental end.

-- 
Jonathan Dataweaver Lang


Re: r29111 - docs/Perl6/Spec

2009-11-18 Thread Darren Duncan

Moritz Lenz wrote:

On Wed, Nov 18, 2009 at 12:33:35AM -0800, Darren Duncan wrote:
For example, say I want the following expression to result in a FatRat 
because presumably that's the only type which will represent the result 
value exactly:


  45207196 * 10 ** -37

How should that be spelled out in terms of 3 integers?


why 3?


I think Jon Lang gave a good reply to that.

I will also add, because that's conceptually what an IEEE float does, and 
technically an IEEE float is still exact precision but it is limited in what 
values it can represent so selecting an IEEE float value in the first place may 
involve rounding, but once you have, the 3-integer representation of a rational 
allows the float to be represented as a rational, tersely, and also radix 
agnostically if the 2 or 10 is explicit.  And it works with just-as-minimal 
memory use when you convert from a 64-bit float like 8.125*2**-4000.



FatRat.new(45207196, 10**37);

And note that a decimal-specific answer isn't what I want, since I want  
something that would also work for this:


  45207196 * 11 ** -37


FatRat.new(45207196, 11**37);


Solomon Foster wrote:

What's your objection to FatRat.new(45207196, 11 ** 37)?


Well, for one thing, that's not the same value.  I had a -37 as the exponent, 
designating a small non-integer rational value, whereas the FatRat example had 
flipped this around to 37, not the same value.


Now I'm sure the format you showed looks great, but my concern is, does simply 
saying this:


  11 ** -37

... result in a FatRat and if not then how do I write 11^-37 in Perl 6 such 
that the resulting object retains the full precision of the value?


-- Darren Duncan


r29111 - docs/Perl6/Spec

2009-11-17 Thread pugs-commits
Author: lwall
Date: 2009-11-17 18:43:12 +0100 (Tue, 17 Nov 2009)
New Revision: 29111

Modified:
   docs/Perl6/Spec/S02-bits.pod
Log:
[S02] more Rat and Ratio clarification


Modified: docs/Perl6/Spec/S02-bits.pod
===
--- docs/Perl6/Spec/S02-bits.pod2009-11-17 17:28:47 UTC (rev 29110)
+++ docs/Perl6/Spec/S02-bits.pod2009-11-17 17:43:12 UTC (rev 29111)
@@ -649,12 +649,11 @@
 machines that are not natively 2's complement.  You must convert to
 and from CInt to do portable bitops on such ancient hardware.)
 
-(CNum may support arbitrary-precision floating-point arithmetic, but
-is not required to unless we can do so portably and efficiently.  CNum
-must support the largest native floating point format that runs at full
-speed.)
+CNum must support the largest native floating point format that
+runs at full speed.  It may be bound to an arbitrary precision type,
+but by default it is the same type as a native Cnum.  See below.
 
-CRat supports arbitrary precision rational arithmetic.
+CRat supports extended precision rational arithmetic.
 Dividing two CInt objects using C infix:/  produces a
 a CRat, which is generally usable anywhere a CNum is usable, but
 may also be explicitly cast to CNum.  (Also, if either side is
@@ -688,8 +687,14 @@
 the Big Bang with picosecond precision.  Though perhaps not with
 picosecond accuracy...)
 
-For applications that really need arbitrary precision denominators
-as well as numerators, CRatio may be used, which is defined as CInt/Int.
+For applications that really need arbitrary precision denominators as
+well as numerators at the cost of performance, CRatio may be used,
+which is stored as CInt/Int, that is, as arbitrary precision in
+both parts.  There is no literal form for a CRatio, so it must
+be constructed using CRatio.new($nu,$de).  In general, only math
+operators with at least one CRatio argument will return another
+CRatio, to prevent accidental promotion of reasonably fast CRat
+values into arbitrarily slow CRatio values.
 
 =item *