digitalmars.D - Big Integers Online

• Arcane Jill (13/13) May 29 2004 I have placed source code for "etc.bigint", a module and package for man...
• J Anderson (4/18) May 29 2004 Why was big int made a class? Why not a struct? Do you intend to extend...
• Arcane Jill (13/14) May 29 2004 1. Ease of initialization. a = new Int(5); is better than Int a; a.init(...
• J Anderson (4/22) May 29 2004 That's fine I was just asking.
• J Anderson (6/13) May 29 2004 You do know you can go:
• Walter (17/25) Jun 02 2004 a.init(5);
• Arcane Jill (13/25) Jun 03 2004 Thanks. In the long term I will think seriously about this. For now, it ...
• Norbert Nemec (13/31) Jun 03 2004 For that purpose, I would think it would make sense to split the problem...
• Arcane Jill (4/5) May 29 2004 I don't think so. I hadn't planned to. Maybe we could add "final" to mak...
• Ivan Senji (26/39) May 29 2004 Now for some stupid questions:
• Arcane Jill (30/49) May 29 2004 Well, I only included source files. Guess I should have included a lib y...
• DemmeGod (2/15) May 30 2004
• Arcane Jill (92/94) May 30 2004 Ahem. Embarrassing confession time...
• Andy Friesen (21/32) May 30 2004 Here's a SConstruct. (SCons is hosted at )
• DemmeGod (4/7) May 30 2004 Would you be referring to the bug I posted on SF:
• Ivan Senji (32/36) May 30 2004 about
• Lars Ivar Igesund (26/39) May 30 2004 Below follows a main.aap that can build and install bigint. A-A-P can be
• Andy Friesen (6/9) May 30 2004 I like that SCons is an API as opposed to a language. This has the
• Stephan Wienczny (6/20) May 30 2004 IMHO such tools have to be easy to use. I don't want to have to write
• Andy Friesen (7/12) May 30 2004 I agree on all points except the last. Guess who added D support to
• Lars Ivar Igesund (7/23) May 31 2004 IMO, Python is not a good argument here. A-A-P is implemented in Python,...
• Paolo Invernizzi (12/13) May 31 2004 BTW, Andy, can you add this little patch on dmd.py?
• Walter (9/11) Jun 02 2004 I try
• Ivan Senji (19/73) May 30 2004 can
• Arcane Jill (5/17) May 30 2004 I have now fixed this embarrassing bug and uploaded the new version to t...
• Walter (6/16) Jun 02 2004 that
• Arcane Jill (3/6) Jun 02 2004 Now that's one I missed! Well spotted. Ok - will add that one sometime s...
• hellcatv hotmail.com (2/15) May 29 2004
• Stewart Gordon (13/17) Jun 01 2004
• Arcane Jill (12/18) Jun 01 2004 Err... you've got me there. Historical reasons, I guess. I think some of...
• Arcane Jill (15/15) Jun 02 2004 Following Stewart Gordon's suggestions, the copy constructor and the dup...
• Derek Parnell (12/31) Jun 02 2004 I am *so* impressed! This is an excellent piece of work. Well done indee...
• Arcane Jill (10/19) Jun 02 2004 *) a += b modifes the object referenced by a.
• Derek Parnell (25/52) Jun 03 2004 Thanks. I understand what is happening here.
• Arcane Jill (14/28) Jun 03 2004 Take a pointer. Given knowledge of the internals of Int it would then be
• Ivan Senji (14/46) Jun 03 2004 udpated
• Arcane Jill (9/13) Jun 03 2004 Nope. You'll find that c === a after that. And multiplying by 1 won't he...
• Ivan Senji (36/50) Jun 03 2004 You didn't notice that i also said "or maybe i didn't?"
• Derek Parnell (15/49) Jun 03 2004 True.
• Kevin Bealer (20/27) Jun 03 2004 Assuming no bugs, this example will work without deep copy. The "+" cre...
• Derek Parnell (7/24) Jun 04 2004 Thanks. This all makes good sense. I didn't realize, but should have, th...
I have placed source code for "etc.bigint", a module and package for manipulated
unlimited precision integers, online at:

http://www.fast-forward.info/ramonsky/stuff/d/bigint.html

(PS. I found it mildly inconvenient that I had to put supporting files in
directory "etc/bigint_files/" instead of "etc/bigint/", because D wouldn't let
me have a module and a directory with the same path).

There is no binary - it's "build-it-yourself". But there /is/ documentation.

Over the next few days I'll try to get this also copied onto dsource (maybe even
with a binary this time, who knows?)

By the way - how does one persuade the dmd linker to produce a library? Probably
a dumb question I know, but I always just linked everything against main to get
an executable.

Arcane Jill

May 29 2004
Arcane Jill wrote:

I have placed source code for "etc.bigint", a module and package for manipulated
unlimited precision integers, online at:

http://www.fast-forward.info/ramonsky/stuff/d/bigint.html

(PS. I found it mildly inconvenient that I had to put supporting files in
directory "etc/bigint_files/" instead of "etc/bigint/", because D wouldn't let
me have a module and a directory with the same path).

There is no binary - it's "build-it-yourself". But there /is/ documentation.

Over the next few days I'll try to get this also copied onto dsource (maybe even
with a binary this time, who knows?)

By the way - how does one persuade the dmd linker to produce a library? Probably
a dumb question I know, but I always just linked everything against main to get
an executable.

Arcane Jill

Why was big int made a class? Why not a struct?  Do you intend to extend it?

--

May 29 2004
In article <c99nfj$1nrf$1 digitaldaemon.com>, J Anderson says...

Why was big int made a class? Why not a struct?

1. Ease of initialization. a = new Int(5); is better than Int a; a.init(5);

2. Most importantly (to me). Only classes can have a destructor. In a
version(Secure) build, the destructor wipes the memory which held the Int's
value. This is important in cryptography, since big integers may hold
cryptographic keys, etc., and you don't want those values lying around in memory
indefinitely. (In a non version(Secure), there is no destructor, of course).

Regardless of whether I had used a struct or a class, there's a dynamic array
inside there, and that would always have been passed by reference, even in a
struct, so there really wouldn't have been much gain. Constructors and
destructors were the deciding factors for me.

Jill

May 29 2004
Arcane Jill wrote:

In article <c99nfj$1nrf$1 digitaldaemon.com>, J Anderson says...

Why was big int made a class? Why not a struct?

1. Ease of initialization. a = new Int(5); is better than Int a; a.init(5);

2. Most importantly (to me). Only classes can have a destructor. In a
version(Secure) build, the destructor wipes the memory which held the Int's
value. This is important in cryptography, since big integers may hold
cryptographic keys, etc., and you don't want those values lying around in memory
indefinitely. (In a non version(Secure), there is no destructor, of course).

Regardless of whether I had used a struct or a class, there's a dynamic array
inside there, and that would always have been passed by reference, even in a
struct, so there really wouldn't have been much gain. Constructors and
destructors were the deciding factors for me.

Jill

That's fine I was just asking.

--

May 29 2004
Arcane Jill wrote:

In article <c99nfj$1nrf$1 digitaldaemon.com>, J Anderson says...

Why was big int made a class? Why not a struct?

1. Ease of initialization. a = new Int(5); is better than Int a; a.init(5);

You do know you can go:

Int a = a();

with opCall.

--

May 29 2004
Antti =?iso-8859-1?Q?Syk=E4ri?= <jsykari gamma.hut.fi> writes:
In article <c99pq0$1r32$2 digitaldaemon.com>, J Anderson wrote:
You do know you can go:

Int a = a();

You probably meant:

Int a = Int();

-A

--
I will not be using Plan 9 in the creation of weapons of mass destruction
to be used by nations other than the US.

May 30 2004
Antti Sykäri wrote:

In article <c99pq0$1r32$2 digitaldaemon.com>, J Anderson wrote:

You do know you can go:

Int a = a();

You probably meant:

Int a = Int();

-A

Or that as well ;)

--

May 30 2004
hellcatv hotmail.com writes:
private import etc.bigint;

int main (char args[][]) {
Int i = new Int("730750818665451459101842416358141509827966271488");
char [] v = i.toString();
printf ("%.*s %.*s = ",v,v);
v = (i*i).toString();
printf ("%.*s\n",v);
return 0;
}

730750818665451459101842416358141509827966271488
730750818665451459101842416358141509827966271488 = Error: AssertError Failure
etc/bigint_files/lowlevel.d(50)

looks problematic...
hope ye' can figure it out...

May 30 2004
In article <c9dtp8$1bf3$1 digitaldaemon.com>, hellcatv hotmail.com says...
private import etc.bigint;

int main (char args[][]) {
Int i = new Int("730750818665451459101842416358141509827966271488");
char [] v = i.toString();
printf ("%.*s %.*s = ",v,v);
v = (i*i).toString();
printf ("%.*s\n",v);
return 0;

Wow. Well, I guess that's what asserts are FOR. In C++ the code would have
carried on and got the wrong answer. (Nice one, Walter!)

Anyway, I have reproduced it. I will let you know when I've fixed it. Hopefully
sometime today.

Jill

PS. I can make libraries now, so hopefully the next release will be easier to
get going.

May 31 2004
In article <c9eosp$2k30$1 digitaldaemon.com>, Arcane Jill says...

Anyway, I have reproduced it. I will let you know when I've fixed it. Hopefully
sometime today.

Fixed. New version online, same place. (Looking forward to moving to dsource
though.)

Jill

May 31 2004
hellcatv hotmail.com writes:
In article <c9et6g$2pt4$1 digitaldaemon.com>, Arcane Jill says...
In article <c9eosp$2k30$1 digitaldaemon.com>, Arcane Jill says...

Anyway, I have reproduced it. I will let you know when I've fixed it. Hopefully
sometime today.

Fixed. New version online, same place. (Looking forward to moving to dsource
though.)

Jill

I'd like to mention that you have a compiler error on non x86 machines:
defined
basically you need to move uint xi into the version() { tag.

Also: you fixed the test case I posted, but this one isn't fixed (same failure):

import etc.bigint;
int main (char args[][]) {
Int i = new
Int("1557113549234358496979015513794451750344390547442359561355264");
Int j = new Int ("18446744073709551616");

char [] v = i.toString();
char [] u = j.toString();
printf ("%.*s %.*s = ",v,u);
v = (i*j).toString();
printf ("%.*s\n",v);
return 0;
}

May 31 2004
In article <c9g1a3$1ab1$1 digitaldaemon.com>, hellcatv hotmail.com says...
Also: you fixed the test case I posted, but this one isn't fixed (same failure):

Will fix tonight.

I should be able to move everything to dsource soon too, but I'll keep a
most-fixed version on my website anyway, at least for a time. I'll also add in
those big rationals one we're on dsource.

Arcane Jill

PS. TEMPORARY WORKAROUND - I suspect that if you build with
version(DisableKaratsuba) the problem may go away. Disallowing the more complex
(but possibly faster) Karatsuba multiplication algorithm forces the lib to use
classical long-multiplication, which is much simpler, and unlikely to be buggy.
(But obviously I will fix the bug anyway).

Jun 01 2004
Will fix tonight.

Jill

Jun 01 2004
"Walter" <newshound digitalmars.com> writes:
"Arcane Jill" <Arcane_member pathlink.com> wrote in message
news:c9hatr$3pd$1 digitaldaemon.com...
PS. TEMPORARY WORKAROUND - I suspect that if you build with
version(DisableKaratsuba) the problem may go away. Disallowing the more

complex
(but possibly faster) Karatsuba multiplication algorithm forces the lib to

use
classical long-multiplication, which is much simpler, and unlikely to be

buggy.

This sounds like a job for DbC! I suggest adding an 'out' postcondition for
the Karatsuba algorithm. In that postcondition, do the classical
multiplication, then assert that the results match. For debug builds, this
will be a great confidence builder in making sure the more complex code is
right.

Jun 02 2004
In article <c9l5vg$2ljv$2 digitaldaemon.com>, Walter says...
This sounds like a job for DbC! I suggest adding an 'out' postcondition for
the Karatsuba algorithm. In that postcondition, do the classical
multiplication, then assert that the results match. For debug builds, this
will be a great confidence builder in making sure the more complex code is
right.

I'm ahead of you there. My class has made that test all along. The reported bug
(which I've actually fixed now) was detected by a DbC assert - though not that
one, as one of the lower-level functions asserted in the middle of executing the
Karatsuba algorithm. Thanks to you, my friend, it was possible to isolate this
error and fix it very fast.

This class is well and truly DbC'ed. The out conditions really do test whether
the answer is right wherever it can, for as many functions as possible.

For this reason, of course, the (theoreticaly faster) Karatsuba algorithm is
actually much /slower/ in a debug build, because it calls the classical
algorithm to check whether it got the answer right! Only in a release build
could it actually be faster.

Jill

Jun 02 2004
"Walter" <newshound digitalmars.com> writes:
"Arcane Jill" <Arcane_member pathlink.com> wrote in message
news:c99o8r$1p31$1 digitaldaemon.com...
In article <c99nfj$1nrf$1 digitaldaemon.com>, J Anderson says...

Why was big int made a class? Why not a struct?

1. Ease of initialization. a = new Int(5); is better than Int a;

a.init(5);
2. Most importantly (to me). Only classes can have a destructor. In a
version(Secure) build, the destructor wipes the memory which held the

Int's
value. This is important in cryptography, since big integers may hold
cryptographic keys, etc., and you don't want those values lying around in

memory
indefinitely. (In a non version(Secure), there is no destructor, of

course).

Since the GC is allowed to move memory around (even though the current
implementation does not) in order to do compaction, wiping memory on a
delete is not reliable. I suggest it would be better to allocate the secure
array using std.c.stdlib.malloc, and then when explicitly free'ing it with
std.c.stdlib.free, do the wipe. That way you'll be in complete control of
any copies.

There's still another problem, though. D's GC does not *guarantee* that
destructors will get run for non-auto objects. Therefore, you might want to
keep a list of all the secure arrays created that haven't been wiped yet,
then on program close with a module destructor, go through the list and wipe
any remaining ones.

Jun 02 2004
In article <c9l5vg$2ljv$1 digitaldaemon.com>, Walter says...

Since the GC is allowed to move memory around (even though the current
implementation does not) in order to do compaction, wiping memory on a
delete is not reliable. I suggest it would be better to allocate the secure
array using std.c.stdlib.malloc, and then when explicitly free'ing it with
std.c.stdlib.free, do the wipe. That way you'll be in complete control of
any copies.

matter, as (a) the crypto lib doesn't exist yet, and (b) the current
implementation of the gc doesn't move memory around. But thank you for pointing
this out. I will take your advice seriously, and my class will do the right
thing, in time.

There's still another problem, though. D's GC does not *guarantee* that
destructors will get run for non-auto objects.

What!!??? Sorry - I don't get that.

Then what's the point of a destructor? You might as well prohibit destructors on
non-auto objects if that's true.

Please could you explain this behavior? Just assume I'm really stupid and know
nothing about how garbage collectors work.

Therefore, you might want to
keep a list of all the secure arrays created that haven't been wiped yet,
then on program close with a module destructor, go through the list and wipe
any remaining ones.

It's a thought. Ta.

Arcane Jill

Jun 03 2004
Norbert Nemec <Norbert.Nemec gmx.de> writes:
Arcane Jill wrote:

In article <c99nfj$1nrf$1 digitaldaemon.com>, J Anderson says...

Why was big int made a class? Why not a struct?

1. Ease of initialization. a = new Int(5); is better than Int a;
a.init(5);

2. Most importantly (to me). Only classes can have a destructor. In a
version(Secure) build, the destructor wipes the memory which held the
Int's value. This is important in cryptography, since big integers may
hold cryptographic keys, etc., and you don't want those values lying
around in memory indefinitely. (In a non version(Secure), there is no
destructor, of course).

Regardless of whether I had used a struct or a class, there's a dynamic
array inside there, and that would always have been passed by reference,
even in a struct, so there really wouldn't have been much gain.
Constructors and destructors were the deciding factors for me.

For that purpose, I would think it would make sense to split the problem:
put the BigInt functionality into a struct for general purpose, and if you
need detailed control over the storage for security, box it up into a
class.

You are right, that the implementation has to be based on a dynamic array,
so you will get reference semantics in any case, but if you implement it as
a class, you will get reference-to-reference behavior, which will certainly
me even more confusing. Having a struct that contains an array reference
will give behavior similar to strings. Any D programmer should be used to
that. Reference-to-reference on the other hand will give some really
strange effects.

Jun 03 2004
In article <c99nfj$1nrf$1 digitaldaemon.com>, J Anderson says...

Do you intend to extend it?

I don't think so. I hadn't planned to. Maybe we could add "final" to make that
clear. But you never know - someone might want to.

Jill

May 29 2004
"Ivan Senji" <ivan.senji public.srce.hr> writes:
Now for some stupid questions:
How do i use it?
I got it working by including al of the files in bigint_files
in my project (i am using DIDE), is it the right way?

I also got an error message about exceptions being
in two packages or something like that, and there were two
deprecated C-style casts.

When i finally got it to work i tried:

import std.c.stdio;
import etc.bigint;

int main(char[][] args)
{
Int n= new Int("123456");

printf("n = %.*s",n.toString);
}

and it prints:
n = 23456

i tried it with acouple of numbers and i never get the first digit.

"Arcane Jill" <Arcane_member pathlink.com> wrote in message
news:c99mrv$1mv6$1 digitaldaemon.com...
I have placed source code for "etc.bigint", a module and package for

manipulated
unlimited precision integers, online at:

http://www.fast-forward.info/ramonsky/stuff/d/bigint.html

(PS. I found it mildly inconvenient that I had to put supporting files in
directory "etc/bigint_files/" instead of "etc/bigint/", because D wouldn't

let
me have a module and a directory with the same path).

There is no binary - it's "build-it-yourself". But there /is/

documentation.
Over the next few days I'll try to get this also copied onto dsource

(maybe even
with a binary this time, who knows?)

By the way - how does one persuade the dmd linker to produce a library?

Probably
a dumb question I know, but I always just linked everything against main

to get
an executable.

Arcane Jill


May 29 2004
In article <c9a37n$282p$1 digitaldaemon.com>, Ivan Senji says...
Now for some stupid questions:
How do i use it?

Well, I only included source files. Guess I should have included a lib you can
link against, but it's early days.

I got it working by including al of the files in bigint_files
in my project (i am using DIDE), is it the right way?

No. It *should* be as simple as "import etc.bigint;". That works for me. The
supporting modules are supposed to be "behind the scenes" (though actually still
individually importable if you really want to).

The way I build it is as follows:

(1) Separately compile each source file, using the -I compiler switch so that
the compiler knows where to start looking for the etc tree.

(2) Compile your own source file(s), again with -I to tell it where to find the
bigint files.

(3) Link all of those files together.

I agree that this is messy. I think I should probably get some pre-built libs
together after the project is moved to dsource.

I also got an error message about exceptions being
in two packages or something like that.

I think it's possible that without the -I switch, the compiler may not be able
to find some things. I can only guess that that's the problem.

If you want, I could always post the complete set of command lines emitted by my
build process. You might not necessarily want to copy that (as I keep debug objs
separately from release objs) but it might help us figure out what the problem
is.

and there were two
deprecated C-style casts.

Feel free to ditch them. After dsource, you'll be able to fix that for everyone,
but for now, if you give the file and line numbers, I can fix it in my
mastercopy.

When i finally got it to work i tried:

import std.c.stdio;
import etc.bigint;

int main(char[][] args)
{
Int n= new Int("123456");

printf("n = %.*s",n.toString);
}

and it prints:
n = 23456

You are correct. It's a bug. I just reproduced it. I will fix it and add that
one to the unit tests. Will let you know when it's done.

i tried it with acouple of numbers and i never get the first digit.

My apologies. It worked once upon a time. I must assume I subsequently broke it.
Most things are unit tested to prevent that from happening. I can't imagine how
I was so stupid as to let that one slip by.

Will get back to you when it's fixed.

Arcane Jill.

May 29 2004
DemmeGod <me demmegod.com> writes:
Why not write a makefile, or better yet a Scons SConstruct file?

John

The way I build it is as follows:

(1) Separately compile each source file, using the -I compiler switch so
that the compiler knows where to start looking for the etc tree.

(2) Compile your own source file(s), again with -I to tell it where to
find the bigint files.

(3) Link all of those files together.

I agree that this is messy. I think I should probably get some pre-built
libs together after the project is moved to dsource.


May 30 2004
In article <pan.2004.05.30.07.23.32.756180 demmegod.com>, DemmeGod says...
Why not write a makefile, or better yet a Scons SConstruct file?

John

Ahem. Embarrassing confession time...

Because I can't write makefiles. And I don't know what a Scons SConstruct file
is.

See - although I can /use/ makefiles, I always seem to get them wrong when I try
to hand craft them, no matter how many times I read through the man page. I'm
spoilt on Windows GUIs now.

I made myself a custom build utility. You see, in D, EVERYTHING we need to know
about what files to compile and link is contained within the ".d" files
themselves. My tool starts at the file containing main(), recurses through all
imports, discovers all dependencies, figures out what to build and what not to
build, and then executes the commands to achieve that. Then it links them all
together. The advantage of this system is that to add a module to the build
process, or to remove a module from the build process, all I have to do is ...
well ... nothing. If there's an import statement referring to it in a file
reachable from main, then it's in, otherwise it's not. No makefile. All I need
is a configuration file telling it what version symbols to define (and even
that's optional if I want the default of none at all).

Advantages for me are ease of use, plus not having to write a makefile. (And not
having to tweak it every time I add or remove a file).

Disadvantages are that it's not-standard. Although I could let other people have
a bash at using my home made DMake thingy, most people don't like non-standard
builders. Not only that, but my cunning scheme will only work for D. As soon as
any C files try to get in on the act, it will all fall over.

But...

If any makefile experts out there would like to help me out by building a
makefile for me, I certainly wouldn't say no for the assistance. The commands
emitted by my builder (when everything is out of date) are listed below. These
are for a debug build. For a release build, change "Debug" to "Release" and
"-debug -g -inline -unittest" to "-release -O" throughout. I should add that the
below trace uses *my* directory structure and so won't work for anyone else.
Also, this just links all the files together, including "main.d" (the first one
compiled) which is *NOT* part of the lib, it's just there so that there's a
main() and I can make an executable.

I actually don't know how to make a D library. The manual is very clear about
about how to make executables, and lists command line switches for the D
compiler, but there's a lot less information about the D linker. As you can see
from the below trace, I've been using dmd itself to invoke the linker
indirectly.

So, er, help anyone?

Objectives:
(1) make a makefile that will work for everyone, and
(2) tell me how to make a D library instead of an executable.

=====================================================
THE OUTPUT OF JILL'S BUILD PROCESS
(building "main.d" linked to all of the bigint files)
(These lines will wrap. Hope you can untangle them)
=====================================================

# This directory is not part of the released package
cd X:\D\Modules\etc\bigint_test

# And nor is this file
C:\dmd\bin\dmd -c .\main.d  -debug -g -inline -unittest -IX:\D\Modules
-od.\Debug

# But from here on, it's all bigint stuff
C:\dmd\bin\dmd -c X:\D\Modules\etc\bigint.d  -debug -g -inline -unittest
-IX:\D\Modules -odX:\D\Modules\etc\Debug

C:\dmd\bin\dmd -c X:\D\Modules\etc\bigint_files\bigint.d  -debug -g -inline
-unittest -IX:\D\Modules -odX:\D\Modules\etc\bigint_files\Debug

C:\dmd\bin\dmd -c X:\D\Modules\etc\bigint_files\prime.d  -debug -g -inline
-unittest -IX:\D\Modules -odX:\D\Modules\etc\bigint_files\Debug

C:\dmd\bin\dmd -c X:\D\Modules\etc\bigint_files\factorial.d  -debug -g -inline
-unittest -IX:\D\Modules -odX:\D\Modules\etc\bigint_files\Debug

C:\dmd\bin\dmd -c X:\D\Modules\etc\bigint_files\exception.d  -debug -g -inline
-unittest -IX:\D\Modules -odX:\D\Modules\etc\bigint_files\Debug

C:\dmd\bin\dmd -c X:\D\Modules\etc\bigint_files\multiply.d  -debug -g -inline
-unittest -IX:\D\Modules -odX:\D\Modules\etc\bigint_files\Debug

C:\dmd\bin\dmd -c X:\D\Modules\etc\bigint_files\radix.d  -debug -g -inline
-unittest -IX:\D\Modules -odX:\D\Modules\etc\bigint_files\Debug

C:\dmd\bin\dmd -c X:\D\Modules\etc\bigint_files\modexp.d  -debug -g -inline
-unittest -IX:\D\Modules -odX:\D\Modules\etc\bigint_files\Debug

C:\dmd\bin\dmd -c X:\D\Modules\etc\prime.d  -debug -g -inline -unittest
-IX:\D\Modules -odX:\D\Modules\etc\Debug

C:\dmd\bin\dmd -c X:\D\Modules\etc\bigint_files\lowlevel.d  -debug -g -inline
-unittest -IX:\D\Modules -odX:\D\Modules\etc\bigint_files\Debug

C:\dmd\bin\dmd -c X:\D\Modules\etc\bigint_files\modinv.d  -debug -g -inline
-unittest -IX:\D\Modules -odX:\D\Modules\etc\bigint_files\Debug

C:\dmd\bin\dmd -c X:\D\Modules\etc\bigint_files\gcd.d  -debug -g -inline
-unittest -IX:\D\Modules -odX:\D\Modules\etc\bigint_files\Debug

C:\dmd\bin\dmd -g X:\D\Modules\etc\bigint_files\Debug\exception.obj
X:\D\Modules\etc\bigint_files\Debug\lowlevel.obj
X:\D\Modules\etc\bigint_files\Debug\multiply.obj
X:\D\Modules\etc\bigint_files\Debug\bigint.obj
X:\D\Modules\etc\bigint_files\Debug\gcd.obj
X:\D\Modules\etc\bigint_files\Debug\modinv.obj
X:\D\Modules\etc\bigint_files\Debug\modexp.obj X:\D\Modules\etc\Debug\prime.obj
X:\D\Modules\etc\bigint_files\Debug\prime.obj
X:\D\Modules\etc\bigint_files\Debug\factorial.obj
X:\D\Modules\etc\Debug\bigint.obj .\Debug\main.obj   -ofbigint_test.exe | tail
-n+4

move bigint_test.exe Debug\bigint_test.exe

move bigint_test.map Debug\bigint_test.map

May 30 2004
Andy Friesen <andy ikagames.com> writes:
Arcane Jill wrote:
In article <pan.2004.05.30.07.23.32.756180 demmegod.com>, DemmeGod says...

Why not write a makefile, or better yet a Scons SConstruct file?

John

Ahem. Embarrassing confession time...

Because I can't write makefiles. And I don't know what a Scons SConstruct file
is.

Here's a SConstruct. (SCons is hosted at <http://www.scons.org>)

This is ever so slightly different in that all the .obj files get dumped
in with the source, but that's because I'm a gimp and need to update the
SCons tool to be better.

import os
from glob import glob

env = Environment(ENV=os.environ)
env.Append(DFLAGS=Split('''
-debug -g -inline -unittest
''')
)
env.Append(DPATH='#') # appends the directory containing SConstruct
to the path

SRC = (
glob('etc/*.d') +
glob('etc/bigint_files/*.d')
)

bigint = env.Program('bigint', SRC)
install = env.Install('#/Debug', bigint)

-- andy

May 30 2004
DemmeGod <me demmegod.com> writes:
Would you be referring to the bug I posted on SF:
http://sourceforge.net/tracker/index.php?func=detail&aid=952905&group_id=30337&atid=398971

that I don't think _anybody_ has even read?

On Sun, 30 May 2004 08:43:49 -0700, Andy Friesen wrote:

This is ever so slightly different in that all the .obj files get dumped
in with the source, but that's because I'm a gimp and need to update the
SCons tool to be better.


May 30 2004
"Ivan Senji" <ivan.senji public.srce.hr> writes:
"Arcane Jill" <Arcane_member pathlink.com> wrote in message
news:c9cu9v$1pu$1 digitaldaemon.com...
In article <pan.2004.05.30.07.23.32.756180 demmegod.com>, DemmeGod says...
...
I actually don't know how to make a D library. The manual is very clear

...

I didn't know also but i looked at what DIDE does and a minute later i have
a library:
So here it is:

C:\dmd\bin\dmd.exe -O -inline -release -c  -I. -I.. -odE:\DLANGU~1\BIGINT~1
"E:\D language\bigintlib\bigint.d"
"E:\D language\bigintlib\exception.d"
"E:\D language\bigintlib\factorial.d"
"E:\D language\bigintlib\gcd.d"
"E:\D language\bigintlib\lowlevel.d"
"E:\D language\bigintlib\modexp.d"
"E:\D language\bigintlib\modinv.d"
"E:\D language\bigintlib\multiply.d"
"E:\D language\bigintlib\prime.d"
"E:\D language\bigintlib\squareroot.d"

C:\dmd\bin\..\..\dm\bin\lib.exe -c bigintlib
"E:\DLANGU~1\BIGINT~1\bigint.obj"
"E:\DLANGU~1\BIGINT~1\exception.obj"
"E:\DLANGU~1\BIGINT~1\factorial.obj"
"E:\DLANGU~1\BIGINT~1\gcd.obj"
"E:\DLANGU~1\BIGINT~1\lowlevel.obj"
"E:\DLANGU~1\BIGINT~1\modexp.obj"
"E:\DLANGU~1\BIGINT~1\modinv.obj"
"E:\DLANGU~1\BIGINT~1\multiply.obj"
"E:\DLANGU~1\BIGINT~1\prime.obj"
"E:\DLANGU~1\BIGINT~1\squareroot.obj"

All i have to do is import etc.bigint; and link with bigintlib.lib
and it works. The paths is something you will have to change!

May 30 2004
Lars Ivar Igesund <larsivar igesund.net> writes:
Arcane Jill wrote:

In article <pan.2004.05.30.07.23.32.756180 demmegod.com>, DemmeGod says...

Why not write a makefile, or better yet a Scons SConstruct file?

John

Ahem. Embarrassing confession time...

Because I can't write makefiles. And I don't know what a Scons SConstruct file
is.

Below follows a main.aap that can build and install bigint. A-A-P can be
found at www.a-a-p.org and do the same things as SCons in a less cryptic
syntax (IMHO).

And to everyone; just because I wonder: I see that a lot of people use
SCons; apart from the fact that you heard about it first (most likely),
what makes SCons a better choice than A-A-P?

To just build:
aap

To install:
aap install

BTW, had to add the -d switch as there were C-style casts in the version

main.aap
----------------------
:import d

# All variables can be set at the command line, e.g. :
# > aap PREFIX=/myroot
DEBUG = yes
DDEBUG = -debug
DFLAGS += -inline -unittest -d

LIBDIR = bigintlib # or any other dir you want to put it in (default is lib)
PREFIX = mylibroot # default is /usr/local

Source = etc/*.d
etc/bigint_files/*.d

:lib bigint : $Source ----------------------- Lars Ivar Igesund  May 30 2004 Andy Friesen <andy ikagames.com> writes: Lars Ivar Igesund wrote: And to everyone; just because I wonder: I see that a lot of people use SCons; apart from the fact that you heard about it first (most likely), what makes SCons a better choice than A-A-P? I like that SCons is an API as opposed to a language. This has the effect of obliviating the distinction between using and extending SCons. The fact that SCons is Python, a language I am very much a fan of, doesn't hurt things either. ;) -- andy  May 30 2004 Stephan Wienczny <wienczny web.de> writes: IMHO such tools have to be easy to use. I don't want to have to write too complicated code I'd have to debug later. If I wanted that I could use a bash scipt. AFAIK I don't want to extend the abilities of my building tool I want to use it ;-) Andy Friesen wrote: Lars Ivar Igesund wrote: And to everyone; just because I wonder: I see that a lot of people use SCons; apart from the fact that you heard about it first (most likely), what makes SCons a better choice than A-A-P? I like that SCons is an API as opposed to a language. This has the effect of obliviating the distinction between using and extending SCons. The fact that SCons is Python, a language I am very much a fan of, doesn't hurt things either. ;) -- andy  May 30 2004 Andy Friesen <andy ikagames.com> writes: Stephan Wienczny wrote: IMHO such tools have to be easy to use. I don't want to have to write too complicated code I'd have to debug later. If I wanted that I could use a bash scipt. AFAIK I don't want to extend the abilities of my building tool I want to use it ;-) I agree on all points except the last. Guess who added D support to SCons. ;) Python is easily my favourite language for getting stuff done fast; SCons lets me leverage that while still describing what to do, as opposed to how it ought to be done. (automatic dependancy checking etc) -- andy  May 30 2004 Lars Ivar Igesund <larsivar igesund.net> writes: Andy Friesen wrote: Stephan Wienczny wrote: IMHO such tools have to be easy to use. I don't want to have to write too complicated code I'd have to debug later. If I wanted that I could use a bash scipt. AFAIK I don't want to extend the abilities of my building tool I want to use it ;-) I agree on all points except the last. Guess who added D support to SCons. ;) Yeah :) I wasn't really asking you :) Python is easily my favourite language for getting stuff done fast; SCons lets me leverage that while still describing what to do, as opposed to how it ought to be done. (automatic dependancy checking etc) -- andy IMO, Python is not a good argument here. A-A-P is implemented in Python, and is fairly easy extendable through modules. Also, Python code can be used directly in the recipes, either on a statement-per-statement basis, or in larger blocks. Lars Ivar Igesund  May 31 2004 Paolo Invernizzi <arathorn inwind.it> writes: Andy Friesen wrote: Guess who added D support to SCons. ;) BTW, Andy, can you add this little patch on dmd.py? In the win32 case, modify the: env['DLINKCOM'] = '$DLINK -of$TARGET$SOURCES $DFLAGS$DLINKFLAGS
$_DLINKLIBFLAGS' to env['DLINKCOM'] = '$DLINK -of$TARGET$SOURCES $DFLAGS$DLINKFLAGS
$_DLINKLIBFLAGS' In this way Scons can build DLL on windows using the env.Program builder ( I know, a little crap... but it works ;-) --- Paolo Invernizzi  May 31 2004 Paolo Invernizzi <arathorn inwind.it> writes: Paolo Invernizzi wrote: Ooopss! to -of${TARGET.base}

to

env['DLINKCOM'] = '$DLINK -of$TARGET $SOURCES$DFLAGS $DLINKFLAGS$_DLINKLIBFLAGS'


May 31 2004
"Walter" <newshound digitalmars.com> writes:
"Arcane Jill" <Arcane_member pathlink.com> wrote in message
news:c9cu9v$1pu$1 digitaldaemon.com...
See - although I can /use/ makefiles, I always seem to get them wrong when

I try
to hand craft them, no matter how many times I read through the man page.

Don't feel bad, NOBODY learns how to write makefiles by reading the man
page. The usual way is to take an existing makefile and hack away at it to
make it work for a new project. Incidentally, this is why makefiles tend to

I suspect that make was never designed, it was hacked together in a weekend
by some programmer who never thought much about it <g>.

Jun 02 2004
"Ivan Senji" <ivan.senji public.srce.hr> writes:
"Arcane Jill" <Arcane_member pathlink.com> wrote in message
news:c9bu8h$1oi8$1 digitaldaemon.com...
In article <c9a37n$282p$1 digitaldaemon.com>, Ivan Senji says...
Now for some stupid questions:
How do i use it?

Well, I only included source files. Guess I should have included a lib you

can
link against, but it's early days.

I got it working by including al of the files in bigint_files
in my project (i am using DIDE), is it the right way?

No. It *should* be as simple as "import etc.bigint;". That works for me.

The
supporting modules are supposed to be "behind the scenes" (though actually

still
individually importable if you really want to).

The way I build it is as follows:

(1) Separately compile each source file, using the -I compiler switch so

that
the compiler knows where to start looking for the etc tree.

(2) Compile your own source file(s), again with -I to tell it where to

find the
bigint files.

(3) Link all of those files together.

I agree that this is messy. I think I should probably get some pre-built

libs
together after the project is moved to dsource.

I'll try this! By the way i have to say i like your big integers a lot, they
work
GREAT :)

I also got an error message about exceptions being
in two packages or something like that.

I think it's possible that without the -I switch, the compiler may not be

able
to find some things. I can only guess that that's the problem.

If you want, I could always post the complete set of command lines emitted

by my
build process. You might not necessarily want to copy that (as I keep

debug objs
separately from release objs) but it might help us figure out what the

problem
is.

and there were two
deprecated C-style casts.

Feel free to ditch them. After dsource, you'll be able to fix that for

everyone,
but for now, if you give the file and line numbers, I can fix it in my
mastercopy.

When i finally got it to work i tried:

import std.c.stdio;
import etc.bigint;

int main(char[][] args)
{
Int n= new Int("123456");

printf("n = %.*s",n.toString);
}

and it prints:
n = 23456

You are correct. It's a bug. I just reproduced it. I will fix it and add

that
one to the unit tests. Will let you know when it's done.

i tried it with acouple of numbers and i never get the first digit.

My apologies. It worked once upon a time. I must assume I subsequently

broke it.
Most things are unit tested to prevent that from happening. I can't

imagine how
I was so stupid as to let that one slip by.

Will get back to you when it's fixed.

Arcane Jill.


May 30 2004
import std.c.stdio;
import etc.bigint;

int main(char[][] args)
{
Int n= new Int("123456");

printf("n = %.*s",n.toString);
}

and it prints:
n = 23456

I have now fixed this embarrassing bug and uploaded the new version to the same
place. I have also added that particular example to the unit tests, so it should
never happen again.

My apologies
Arcane Jill

May 30 2004
"Walter" <newshound digitalmars.com> writes:
"Arcane Jill" <Arcane_member pathlink.com> wrote in message
news:c9bu8h$1oi8$1 digitaldaemon.com...
In article <c9a37n$282p$1 digitaldaemon.com>, Ivan Senji says...
int main(char[][] args)
{
Int n= new Int("123456");
printf("n = %.*s",n.toString);
}
and it prints:
n = 23456

You are correct. It's a bug. I just reproduced it. I will fix it and add

that
one to the unit tests. Will let you know when it's done.

Can I suggest another use for DbC? In the toString() function, add an 'out'
postcondition which converts back to an int. Assert that it matches the
original int.

Jun 02 2004
In article <c9l6gn$2mcm$1 digitaldaemon.com>, Walter says...

Can I suggest another use for DbC? In the toString() function, add an 'out'
postcondition which converts back to an int. Assert that it matches the
original int.

Now that's one I missed! Well spotted. Ok - will add that one sometime soon.

Jill

Jun 02 2004
hellcatv hotmail.com writes:
You rock, Arcane Jill

In article <c99mrv$1mv6$1 digitaldaemon.com>, Arcane Jill says...
I have placed source code for "etc.bigint", a module and package for manipulated
unlimited precision integers, online at:

http://www.fast-forward.info/ramonsky/stuff/d/bigint.html

(PS. I found it mildly inconvenient that I had to put supporting files in
directory "etc/bigint_files/" instead of "etc/bigint/", because D wouldn't let
me have a module and a directory with the same path).

There is no binary - it's "build-it-yourself". But there /is/ documentation.

Over the next few days I'll try to get this also copied onto dsource (maybe even
with a binary this time, who knows?)

By the way - how does one persuade the dmd linker to produce a library? Probably
a dumb question I know, but I always just linked everything against main to get
an executable.

Arcane Jill


May 29 2004
Stewart Gordon <smjg_1998 yahoo.com> writes:
Arcane Jill wrote:

I have placed source code for "etc.bigint", a module and package for
manipulated
unlimited precision integers, online at:

http://www.fast-forward.info/ramonsky/stuff/d/bigint.html

<snip>

1. "Construct an Int having the value value. This is a copy constructor.
It copies by value, not by reference."

You seem to indicate that Int objects are immutable.  In that case, why
bother with the copy constructor and dup method?

2. You have overloaded operators for combining with int and uint.  Why
not long and ulong?

Stewart.

--
My e-mail is valid but not my primary mailbox, aside from its being the
unfortunate victim of intensive mail-bombing at the moment.  Please keep
replies on the 'group where everyone may benefit.

Jun 01 2004
In article <c9i0d5$12or$1 digitaldaemon.com>, Stewart Gordon says...

1. "Construct an Int having the value value. This is a copy constructor.
It copies by value, not by reference."

You seem to indicate that Int objects are immutable.  In that case, why
bother with the copy constructor and dup method?

Err... you've got me there. Historical reasons, I guess. I think some of the lib
code may need to use that constructor internally, and there seemed little point
in making it private. Maybe it would be ok to remove that at this stage, but I'd
have to think hard before taking that step in case it broke anything.

But you're right. Public calls will almost certainly never need it.

2. You have overloaded operators for combining with int and uint.  Why
not long and ulong?

No reason. I just forgot. But it's never too late to add them.

Also missing are constructors from float, double and real, for much the same
reason. They, too, can be added in the future. (Also, it will be dsourced in a
couple of days, so it will be easier for other people to add anything I've
missed out.)

Jill

Jun 01 2004
Following Stewart Gordon's suggestions, the copy constructor and the dup()
function have been removed from the Int class (Ints are immutable, so
copy-by-value is never needed), and constructors have been added for conversion
from long, ulong, float, double and real.

Following my own suggestions, this lib now defines a new type, Bool, which
stores a true boolean value and which will not auto-cast to or from int. All Int
functions which return or accept boolean values now utilise Bool (except
opEquals(), obviously).

now includes the classes Int and Bool. But it seems I have a lot to learn.
Though I've used CVS before (dsource uses Subversion) I've not got to learn all
about trunks, branches, tags and so forth. I'm going to take my time over this,
because I don't want to get it wrong, so - I shall probably not be ready for a
few more days. But come next weekend, hey, who knows?

Jill

Jun 02 2004
Derek Parnell <derek psych.ward> writes:
On Sat, 29 May 2004 09:58:23 +0000 (UTC), Arcane Jill wrote:

I have placed source code for "etc.bigint", a module and package for
manipulated
unlimited precision integers, online at:

http://www.fast-forward.info/ramonsky/stuff/d/bigint.html

(PS. I found it mildly inconvenient that I had to put supporting files in
directory "etc/bigint_files/" instead of "etc/bigint/", because D wouldn't let
me have a module and a directory with the same path).

There is no binary - it's "build-it-yourself". But there /is/ documentation.

Over the next few days I'll try to get this also copied onto dsource (maybe
even
with a binary this time, who knows?)

By the way - how does one persuade the dmd linker to produce a library?
Probably
a dumb question I know, but I always just linked everything against main to get
an executable.

Arcane Jill

I am *so* impressed! This is an excellent piece of work. Well done indeed.
I can't wait for the crypto stuff as this is also an area that I work in.

I'm also a bit slow ;-) Can you give me the "for Dummies" explanation of
why a+=b is not allowed? In my humble brain

a += b;

is syntax sugar for

a = a + b;

so what am I missing here?

--
Derek
3/Jun/04 11:22:48 AM

Jun 02 2004
I'm also a bit slow ;-) Can you give me the "for Dummies" explanation of
why a+=b is not allowed? In my humble brain

a += b;

is syntax sugar for

a = a + b;

so what am I missing here?

*) a += b modifes the object referenced by a.
*) a = a + b modifies the reference a, but not the object (formerly) referenced
by a.

Example: Suppose you have a third Int, named c. And suppose that at some
previous point in the code you had said:

c = a;

Now the difference between + and += becomes:

a += b;    // will modify both a and c
a = a + b; // will modify a, but not c

For this reason, I outlawed += and friends for my class. (+= is fine with
structs, but not with classes. For reasons I won't go into here, Int is a
class).

Arcane Jill

Jun 02 2004
Derek Parnell <derek psych.ward> writes:
On Thu, 3 Jun 2004 06:51:09 +0000 (UTC), Arcane Jill wrote:

I'm also a bit slow ;-) Can you give me the "for Dummies" explanation of
why a+=b is not allowed? In my humble brain

a += b;

is syntax sugar for

a = a + b;

so what am I missing here?

*) a += b modifes the object referenced by a.
*) a = a + b modifies the reference a, but not the object (formerly) referenced
by a.

Example: Suppose you have a third Int, named c. And suppose that at some
previous point in the code you had said:

c = a;

Now the difference between + and += becomes:

a += b;    // will modify both a and c
a = a + b; // will modify a, but not c

Thanks. I understand what is happening here.

For this reason, I outlawed += and friends for my class. (+= is fine with
structs, but not with classes. For reasons I won't go into here, Int is a
class).

Could one have designed the class such that 'a += b' behaved the same as 'a
= a + b'?

As I see it now, you have decided to disturb the normal D behaviour with
respect to Int objects. It seems that the normal behaviour of D for += is
to update the object referred to by 'a' (as you state). Thus any other
variables that refer to the same instance are also 'automagically' udpated
too. This is what D does, right? Now you have disallowed this normal
behaviour. So what if I wanted to use this normal D behaviour, just as I
would for other classes?

offense.

BTW, I presume that what one is supposed to do when taking a copy of a
class object's value is to do ...

c = new Int(a);

rather than

c = a;

I really must start doing more than playing with D...now where *did* I put
that spare time of mine?

--
Derek
Melbourne, Australia
3/Jun/04 5:30:22 PM

Jun 03 2004
In article <c9mkj4$1pdj$1 digitaldaemon.com>, Derek Parnell says...
Thanks. I understand what is happening here.

As I see it now, you have decided to disturb the normal D behaviour with
respect to Int objects. It seems that the normal behaviour of D for += is
to update the object referred to by 'a' (as you state). Thus any other
variables that refer to the same instance are also 'automagically' udpated
too. This is what D does, right? Now you have disallowed this normal
behaviour. So what if I wanted to use this normal D behaviour, just as I
would for other classes?

Take a pointer. Given knowledge of the internals of Int it would then be
possible to modify the object directly, which would then modify the object for
all references to it. Of course, I did not provide *any* functions to allow you
to do this, but given knowledge of the internals of Int (which you could glean
from the source code) you could write functions which did. Not sure why you'd
want to though.

Having said that, not providing certain operator overloads is not "disallowing
normal behavior". There is no rule that says every class must overload all

BTW, I presume that what one is supposed to do when taking a copy of a
class object's value is to do ...

c = new Int(a);

rather than

c = a;

Not any more. I've ditched the copy constructor. Now you *can't* take a copy,
leaving you with no choice but c = a;. There really is no need to deep copy an
immutable object.

Arcane Jill

Jun 03 2004
"Ivan Senji" <ivan.senji public.srce.hr> writes:
"Arcane Jill" <Arcane_member pathlink.com> wrote in message
news:c9ml84$1q9a$1 digitaldaemon.com...
In article <c9mkj4$1pdj$1 digitaldaemon.com>, Derek Parnell says...
Thanks. I understand what is happening here.

As I see it now, you have decided to disturb the normal D behaviour with
respect to Int objects. It seems that the normal behaviour of D for += is
to update the object referred to by 'a' (as you state). Thus any other
variables that refer to the same instance are also 'automagically'

udpated
too. This is what D does, right? Now you have disallowed this normal
behaviour. So what if I wanted to use this normal D behaviour, just as I
would for other classes?

Take a pointer. Given knowledge of the internals of Int it would then be
possible to modify the object directly, which would then modify the object

for
all references to it. Of course, I did not provide *any* functions to

allow you
to do this, but given knowledge of the internals of Int (which you could

glean
from the source code) you could write functions which did. Not sure why

you'd
want to though.

Having said that, not providing certain operator overloads is not

"disallowing
normal behavior". There is no rule that says every class must overload all

BTW, I presume that what one is supposed to do when taking a copy of a
class object's value is to do ...

c = new Int(a);

rather than

c = a;

Not any more. I've ditched the copy constructor. Now you *can't* take a

copy,
leaving you with no choice but c = a;. There really is no need to deep

copy an
immutable object.

I neaded to have a copy of Int (or maybe i didn't?) and
i did it like this:
c = 0 + a;

This does make a copy, doesn't it?

Arcane Jill


Jun 03 2004
In article <c9mmoj$1sbb$1 digitaldaemon.com>, Ivan Senji says...

I neaded to have a copy of Int

Why?

i did it like this:
c = 0 + a;

This does make a copy, doesn't it?

Nope. You'll find that c === a after that. And multiplying by 1 won't help
either. Nor will shifting right or left by zero. The lib is well optimized. But
what I don't get is ... WHY do you need a deep copy?

Jill

PS. If you give me a really good reason why a copy-by-reference is not
sufficient, given that Int is immutable, then I will put dup() back in. I'm
trying to be helpful, not mean.

Jun 03 2004
"Ivan Senji" <ivan.senji public.srce.hr> writes:
"Arcane Jill" <Arcane_member pathlink.com> wrote in message
news:c9n1aq$2as8$1 digitaldaemon.com...
In article <c9mmoj$1sbb$1 digitaldaemon.com>, Ivan Senji says...

I neaded to have a copy of Int

Why?

You didn't notice that i also said "or maybe i didn't?"
Now i'm pretty sure i didn't need a deep copy, but
i only thought i nead it :)

i did it like this:
c = 0 + a;

This does make a copy, doesn't it?

Nope. You'll find that c === a after that. And multiplying by 1 won't help
either. Nor will shifting right or left by zero. The lib is well

optimized. But
what I don't get is ... WHY do you need a deep copy?

Wow! It really is optimized.

PS. I have a problem with Stack Overflow error with this code:
It doesn't happen when seed is smaller!

<CODE>
import std.c.stdio;

import etc.bigint;
import etc.prime;

int main ( char [] [] args )
{
Int seed = new Int("12345678901234567890123456789");
printf("seed = %.*s\n",seed.toString);

Int p = getProbablePrimeLess(seed);
Int q = getProbablePrimeGreater(seed);

printf("seed = %.*s\np    = %.*s\nq    =
%.*s\n",seed.toString,p.toString,q.toString);

printf("prime(p) == %d, prime(q) ==
%d\n",isProbablyPrime(p),isProbablyPrime(q));

Int n = p*q;

printf("n = %.*s\n",n.toString);

Int fi = (p-1)*(q-1);

printf("fi = %.*s\n",fi.toString);

printf("n    = %.*s\n",n.toString);
printf("prime == %d\n",isProbablyPrime(n));
printf("fi   = %.*s\n",fi.toString);
printf("prime == %d\n",isProbablyPrime(fi));

getch();
return 1;
}
</CODE>

Jill

PS. If you give me a really good reason why a copy-by-reference is not
sufficient, given that Int is immutable, then I will put dup() back in.

I'm
trying to be helpful, not mean.


Jun 03 2004
Derek Parnell <derek psych.ward> writes:
On Thu, 3 Jun 2004 07:50:28 +0000 (UTC), Arcane Jill wrote:

In article <c9mkj4$1pdj$1 digitaldaemon.com>, Derek Parnell says...
Thanks. I understand what is happening here.

As I see it now, you have decided to disturb the normal D behaviour with
respect to Int objects. It seems that the normal behaviour of D for += is
to update the object referred to by 'a' (as you state). Thus any other
variables that refer to the same instance are also 'automagically' udpated
too. This is what D does, right? Now you have disallowed this normal
behaviour. So what if I wanted to use this normal D behaviour, just as I
would for other classes?

Take a pointer. Given knowledge of the internals of Int it would then be
possible to modify the object directly, which would then modify the object for
all references to it. Of course, I did not provide *any* functions to allow you
to do this, but given knowledge of the internals of Int (which you could glean
from the source code) you could write functions which did. Not sure why you'd
want to though.

Having said that, not providing certain operator overloads is not "disallowing
normal behavior". There is no rule that says every class must overload all

True.

BTW, I presume that what one is supposed to do when taking a copy of a
class object's value is to do ...

c = new Int(a);

rather than

c = a;

Not any more. I've ditched the copy constructor. Now you *can't* take a copy,
leaving you with no choice but c = a;. There really is no need to deep copy an
immutable object.

I might need one to restore a value on transaction backout.

Int oldVal;

oldVal = a;

a = a + b;
if (DoSomething(a) == 0)
// Restore previous value.
a = oldVal;

--
Derek
Melbourne, Australia
4/Jun/04 1:39:10 PM

Jun 03 2004
In article <c9or5a$1u4v$1 digitaldaemon.com>, Derek Parnell says...
..
I might need one to restore a value on transaction backout.

Int oldVal;

oldVal = a;

a = a + b;
if (DoSomething(a) == 0)
// Restore previous value.
a = oldVal;

Assuming no bugs, this example will work without deep copy.  The "+" creates a
new object; the oldVal still points to the old version.  Immutable means that
objects never change.  "a=a+b" points the reference a at a new object which is
the sum of a and b.

This is a powerful technique.  In garbage collected languages it is common to
implement binary trees and other structures so that you can add new elements to
the tree, and keep the old reference.  You end up with two complete trees that
share all the pieces they have in common.  If you add another element you have a
third tree, again sharing most of the nodes between all the trees.  You can keep
all three and iterate over them; you don't need to know they are shared.

If file systems were done this way, you could keep a "root pointer" to a
filesystem somewhere and later on swap it back in as the top element, restoring
the FS to the previous state instantly.  You could capture a new "whole
filesystem view" as often as every minute with little impact on performance
(unless you are doing a lot of writing), and later on, go back to any period in

(But most FS's don't do this, so never mind.)

Kevin Bealer

Jun 03 2004
Derek Parnell <derek psych.ward> writes:
On Fri, 4 Jun 2004 05:27:37 +0000 (UTC), Kevin Bealer wrote:

In article <c9or5a$1u4v$1 digitaldaemon.com>, Derek Parnell says...
..
I might need one to restore a value on transaction backout.

Int oldVal;

oldVal = a;

a = a + b;
if (DoSomething(a) == 0)
// Restore previous value.
a = oldVal;

Assuming no bugs, this example will work without deep copy.  The "+" creates a
new object; the oldVal still points to the old version.  Immutable means that
objects never change.  "a=a+b" points the reference a at a new object which is
the sum of a and b.

Thanks. This all makes good sense. I didn't realize, but should have, that
the '+' forced a new instance to be created.

--
Derek
Melbourne, Australia
4/Jun/04 5:05:21 PM

Jun 04 2004