Bigint^bigint

57 views
Skip to first unread message

Kurt Pagani

unread,
Mar 8, 2019, 2:00:02 PM3/8/19
to pure-lang
In REDUCE we have

nextprime(10^30); ⇒ 1000000000000000000000000000057

while in Pure we get

> simplify $ nextprime (10L^30L);
1000000000000000019884624838797L

The problem seems to originate from

> 10L^30L;
1e+030
> bigint ans;
1000000000000000019884624838656L

-- not what I expected. Indeed:

> show ^
infixr 2500 ^;
1.0^y::double = 1.0;
(-1.0)^y::double = 1.0 if infp y;
x::double^y::double = __C::pow x y;
x::int^y::int = double x^double y;
x::bigint^y::bigint = double x^double y;
x::int^y::bigint = double x^double y;
x::bigint^y::int = double x^double y;
x::double^y::int = x^double y;
x::double^y::bigint = x^double y;
x::int^y::double = double x^y;
x::bigint^y::double = double x^y;

is revealing the lack of bigint^bigint.

IMO the datatypes "double" and "int" in Pure (may) lead to various confusions.
Are they really necessary? Integer (bigint, without suffix "L") and "float" (mp, arb) ought to be enough nowadays.

What is the general opinion?

Another point I really dislike is the conversion to "double", even if a exact type is possible:

x::int^y::int = double x^double y;

That is, I would expect the result of
x::bigint^y::bigint a bigint as well.

This is by no means veiled criticism (I could change everything for personal use, of course), merely to open a discussion :)






Kurt Pagani

unread,
Mar 8, 2019, 2:22:27 PM3/8/19
to pure...@googlegroups.com
I forgot to mention that using "quote" gives the correct answer :(

// > simplify $ nextprime (quote (10L^30L));
// 1000000000000000000000000000057L

Although consequently letting REDUCE evaluate the "numbers", the vulnerability
will remain in that it seems to me too error-prone when dealing with a lot of code.

Albert Graef

unread,
Mar 13, 2019, 2:14:16 AM3/13/19
to pure...@googlegroups.com
Hi Kurt,

On Fri, Mar 8, 2019 at 8:00 PM Kurt Pagani <nil...@gmail.com> wrote:
In REDUCE we have

nextprime(10^30); ⇒ 1000000000000000000000000000057

while in Pure we get

> simplify $ nextprime (10L^30L);
1000000000000000019884624838797L
 
Well, for better or worse, ^ always yields inexact results in Pure, as / does. To compute exact powers with bigint results, Pure has the pow function:

> simplify $ nextprime (pow 10 30);
1000000000000000000000000000057L

Albert

--
Dr. Albert Gr"af
Computer Music Research Group, JGU Mainz, Germany
Email:  agg...@gmail.com
WWW:    https://plus.google.com/+AlbertGraef

Kurt Pagani

unread,
Mar 13, 2019, 11:15:42 AM3/13/19
to pure...@googlegroups.com
Thank you, Albert :)
I should have known. Actually a fellow worker reported this to me after spending
some time on finding the error in his computations (BTW the same who was looking
for 'lcm'). I'm not so used to int/double anymore (my recollections of C/Fortran
etc. are fading out) because of a consequent use of exact computing (e.g.
mpfr/arb/boost). That's why my question if it's still timely to use it in Pure;)
Best wishes
Kurt
> Email:  agg...@gmail.com <mailto:agg...@gmail.com>
> WWW:    https://plus.google.com/+AlbertGraef
>
> --

Kurt Pagani

unread,
Mar 24, 2019, 12:32:54 PM3/24/19
to pure-lang
Hello Albert

I'm a bit confused about the built-in mixed arithmetic, more preicsely the automated evaluation to "doubles". Although I've been trying hard on finding a method to inhibit such evaluations (without using quotes), it seems impossible (even without primitives, prelude ...):

> pure -n -i

 __ \  |   |  __| _ \    Pure 0.68 (i686-w64-mingw32)
 |   | |   | |    __/    Copyright (c) 2008-2018 by Albert Graef
 .__/ \__,_|_|  \___|    (Type 'help' for help, 'help copying'
_|                       for license information.)


> foo (x/y) = x:y;
> foo (2/3);
foo 0.666666666666667
> namespace bar;
> qq (x/y) = [x,y];
> qq (7/8);
bar::qq 0.875
>

Usually, when clearing the operators [*,/,^,+,-], it works well, however, one may never be sure.
Will it be difficult to provide a switch that inhibits evaluation of "exactp" expressions (?),  that is for instance:

$>pure -i -q
> 2/3;
0.666666666666667   // prefer: 2/3
> clear /
> 2/3;
2/3
> (2/3)*x;
0.666666666666667*x   // dito
> clear *
> (2/3)*x;
2/3*x

> ppp (2/3);
ppp (2/3)
> qqq (x/y) = x:y;
> qqq (2/3);
qqq 0.666666666666667  // dito
>

I had a look into interpreter.cc:

Value *interpreter::builtin_codegen(expr x)
{
  // handle special cases which should be inlined for efficiency: mixed
  // arithmetic, comparisons, logical ops using unboxed integer and floating
  // point values

and - just a guess - have been thinking that it could be done somewhere here? Before filling out a feature request, what do you think?

Best wishes
Kurt

Albert Graef

unread,
Aug 21, 2019, 1:14:41 PM8/21/19
to pure...@googlegroups.com
Hi Kurt (and everybody else),

I have got a lot of catching up to do... It seems that I missed an entire batch of posts while I was at the Linux Audio Conference in Stanford in March, sorry about that. :((

On Sun, Mar 24, 2019 at 5:32 PM Kurt Pagani <nil...@gmail.com> wrote:
I'm a bit confused about the built-in mixed arithmetic, more preicsely the automated evaluation to "doubles". Although I've been trying hard on finding a method to inhibit such evaluations (without using quotes), it seems impossible (even without primitives, prelude ...):

What's wrong with quotes? ;-) I'd say that this is the obvious solution here:

> foo (x/y) = x:y;
> foo (4/3);
foo 1.33333333333333
> foo ('4/3);
4:3

Doesn't look all that clumsy either.

That said, there's namespace bracket feature (https://agraef.github.io/pure-docs/pure.html#namespace-brackets), but I'm not sure that it helps in this specific case, since presumably you don't want to have all those operators live in their own namespace, which means that you have to define *everything* from the ground up. Anyway, a working example of this is my attempt at defining Lucid in Pure, see https://github.com/agraef/pure-lang/blob/master/pure/examples/lucid.pure.

And then there are macros. You could define yourself a helper macro which does the quoting for you. It's a bit clumsy, but it works:

> def Foo x = foo ('x);
> Foo (4/3);
4:3

Better?

and - just a guess - have been thinking that it could be done somewhere here? Before filling out a feature request, what do you think?

Yeah, that seems to be the right place that you're looking at. But seriously, fiddling around with the code generator just to avoid a quote here and there sounds like cracking a nut with a sledgehammer IMHO. ;-)

Cheers,
Albert

--
Dr. Albert Gr"af
Computer Music Research Group, JGU Mainz, Germany

Kurt Pagani

unread,
Aug 21, 2019, 4:03:35 PM8/21/19
to pure...@googlegroups.com
Hi Albert

No worries! Just glad having got vital signs ;)

> What's wrong with quotes? ;-)
Basically I'd agree that quotes were the obvious solution, however, it seems
that some fellows (mis?)use Pure to process Maxima output (via pipe) and have to
set quotes manually (showing little spirit to do that).

I guess that a pre-processing of the output will do it. Presumably they found a
work-around in the meantime.

Grüsse
Kurt
> Email: agg...@gmail.com <mailto:agg...@gmail.com>, web: https://agraef.github.io/
>
> --
> You received this message because you are subscribed to the Google Groups
> "pure-lang" group.
> To unsubscribe from this group and stop receiving emails from it, send an email
> to pure-lang+...@googlegroups.com
> <mailto:pure-lang+...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/pure-lang/CA%2BrUic3X1euZQJKUHVkXADVj2oycr-LhY7rcRWMk-MLgf05r7A%40mail.gmail.com
> <https://groups.google.com/d/msgid/pure-lang/CA%2BrUic3X1euZQJKUHVkXADVj2oycr-LhY7rcRWMk-MLgf05r7A%40mail.gmail.com?utm_medium=email&utm_source=footer>.

Albert Graef

unread,
Aug 21, 2019, 4:16:24 PM8/21/19
to pure...@googlegroups.com
On Wed, Aug 21, 2019 at 10:03 PM Kurt Pagani <nil...@gmail.com> wrote:
I guess that a pre-processing of the output will do it. Presumably they found a
work-around in the meantime.

Yeah, I guess so. They probably could have rewritten the entire compiler backend for LLVM 8 in the time it took me to reply to that message. :))

Best,
Albert

--
Dr. Albert Gr"af
Computer Music Research Group, JGU Mainz, Germany

Kurt Pagani

unread,
Dec 30, 2019, 11:58:36 AM12/30/19
to pure-lang
Hi Albert

You were right, macros will do it :)


kfp@NUC MINGW64 / (master)
$ pure


 __ \  |   |  __| _ \    Pure 0.68 (i686-w64-mingw32)
 |   | |   | |    __/    Copyright (c) 2008-2018 by Albert Graef
 .__/ \__,_|_|  \___|    (Type 'help' for help, 'help copying'
_|                       for license information.)

Loaded prelude from C:/msys64/mingw32/lib/pure/prelude.pure.

> type rational (x::integer / y::integer);  // = bigint y~=0L;
> num (x::integer / y::integer) = x;
> den (x::integer / y::integer) = y;
>
> def (x::number + y::number) = '(x+y);
> def (x::number - y::number) = '(x-y);
> def (x::number / y::number) = '(x/y);
> def (x::number ^ y::number) = '(x^y);
> def (x::number * y::number) = '(x*y);
> 1+1;
1+1
> 1+1==2;
1+1==2
> 1+1===2;
0
> 2*3+6;
2*3+6
> 2*3+6/5-2^(1/2);
2*3+6/5-2^(1/2)
>


without:

> 1+1;
2
> 1+1==2;
1
> 1+1===2;
1
> 2*3+6;
12
> 2*3+6/5-2^(1/2);
5.78578643762691
>

That's great, e.g. when using types like

type bae x::var
   | bae x::integer
   | bae (x::bae + y::bae)
   | bae (x::bae - y::bae)
   | bae (x::bae * y::bae)
   | bae (x::bae / y::bae)
   | bae (x::bae ^ y::bae)
   | bae (- x::bae)
   ;

baep x = typep bae x;


....

Thanks & best wishes
Kurt


Reply all
Reply to author
Forward
0 new messages