mersenneforum.org  

Go Back   mersenneforum.org > Extra Stuff > Linux

Reply
 
Thread Tools
Old 2017-10-08, 22:02   #1
ewmayer
2ω=0
 
ewmayer's Avatar
 
Sep 2002
República de California

3×7×13×43 Posts
Default How to init an array in Posix bc?

Posix bc allows array variables and parameters, but I have only found one-element-at-a-time init to work, e.g. to declare and init a 2-element array 'a':

a[2]; a[0]=1; a[1]=2;

(Interestingly, adding a[2]=3 does not give an error and the resulting 3 element value are correct, so possibly bc auto-expands the array size in such cases, but I wouldn't count on this happening, i.e. best to init only within the declared array index range.)

Especially for many-element arrays it would be really nice to be able to combine declare/init in a fashion akin to C, e.g. 'a[2] = {1,2}', but I have found no syntax for the initializers which works, and websearch turns up only parroted manpages, none of which discuss array-init.

Last fiddled with by ewmayer on 2017-10-08 at 22:03
ewmayer is offline   Reply With Quote
Old 2017-10-08, 22:30   #2
science_man_88
 
science_man_88's Avatar
 
"Forget I exist"
Jul 2009
Dumbassville

2·5·839 Posts
Default

Quote:
Originally Posted by ewmayer View Post
Posix bc allows array variables and parameters, but I have only found one-element-at-a-time init to work, e.g. to declare and init a 2-element array 'a':

a[2]; a[0]=1; a[1]=2;

(Interestingly, adding a[2]=3 does not give an error and the resulting 3 element value are correct, so possibly bc auto-expands the array size in such cases, but I wouldn't count on this happening, i.e. best to init only within the declared array index range.)

Especially for many-element arrays it would be really nice to be able to combine declare/init in a fashion akin to C, e.g. 'a[2] = {1,2}', but I have found no syntax for the initializers which works, and websearch turns up only parroted manpages, none of which discuss array-init.
https://web.archive.org/web/20090501...bc.1posix.html is the best I could find.
science_man_88 is offline   Reply With Quote
Old 2017-10-09, 12:24   #3
paulunderwood
 
paulunderwood's Avatar
 
Sep 2002
Database er0rr

22×1,063 Posts
Default

Quote:
Originally Posted by ewmayer View Post
Posix bc allows array variables and parameters, but I have only found one-element-at-a-time init to work, e.g. to declare and init a 2-element array 'a':

a[2]; a[0]=1; a[1]=2;

(Interestingly, adding a[2]=3 does not give an error and the resulting 3 element value are correct, so possibly bc auto-expands the array size in such cases, but I wouldn't count on this happening, i.e. best to init only within the declared array index range.)

Especially for many-element arrays it would be really nice to be able to combine declare/init in a fashion akin to C, e.g. 'a[2] = {1,2}', but I have found no syntax for the initializers which works, and websearch turns up only parroted manpages, none of which discuss array-init.
It can't be done.

Your first use of a[2]; returns 0, as would the uninitialized a[100];.
paulunderwood is offline   Reply With Quote
Old 2017-10-10, 00:48   #4
bgbeuning
 
Dec 2014

3·5·17 Posts
Default

GNU bc has an extension to allow passing arrays using "call by variable".
It looks like
zero( *a[], n ) {
for( i = 0; i < n; i++ ) a[i] = 0;
}

This is from reading the YACC grammar. I have not tried it.
bgbeuning is offline   Reply With Quote
Old 2017-10-10, 06:31   #5
ewmayer
2ω=0
 
ewmayer's Avatar
 
Sep 2002
República de California

267338 Posts
Default

Quote:
Originally Posted by paulunderwood View Post
It can't be done.

Your first use of a[2]; returns 0, as would the uninitialized a[100];.
For the 2-element-dimensioned array example I gave a[2] returns 0 before I init it, but afterward the value is preserved perfectly fine, at least in my version of bc:
Code:
My-MacBook:src ewmayer$ bc
bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
a[2]; a[0]=1; a[1]=2;
0	<*** ewm: '0' here is return value of array-declaration statement ***
a[2]
0	<*** Out-of-range element prior to initing it
a[2]=3
a[2]
3
a[0]*a[2]
3
a[1]*a[2]
6
a[2]*a[2]
9
Brian, I saw the passing-array-argument stuff, but that does not help with the init issue ... as Paul notes, it appears bc simply was not et up to allow convenience of inits. Similarly, one cannot declare an automatic variable in a bc function and init said variable in the same declaration statement - the init must come via separate statement after the declaration.
ewmayer is offline   Reply With Quote
Old 2017-10-10, 08:46   #6
axn
 
axn's Avatar
 
Jun 2003

2×2,693 Posts
Default

Quote:
Originally Posted by ewmayer View Post
For the 2-element-dimensioned array example I gave a[2] returns 0 before I init it, but afterward the value is preserved perfectly fine, at least in my version of bc:
You are still thinking "a[2]" as a declaration, while paul is saying that it is evaluating the third element of a[].

What happens if you omit your "declaration" a[2] altogether? Will it still work the same?
axn is offline   Reply With Quote
Old 2017-10-10, 09:36   #7
paulunderwood
 
paulunderwood's Avatar
 
Sep 2002
Database er0rr

22×1,063 Posts
Default

Code:
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
a[0]=1; a[1]=2;
a[2]
0
a[2]=3
a[2]
3
a[0]*a[2]
3
a[1]*a[2]
6
a[2]*a[2]
9
Basically, you can think of all possible arrays pre-existing up to the internally set length and that they are all filled with zeroes, until you set a value to an element. In other words, you do not need to declare/dimension an array and undefined/unassigned array elements will return 0.

Last fiddled with by paulunderwood on 2017-10-10 at 09:53
paulunderwood is offline   Reply With Quote
Old 2017-10-10, 23:46   #8
ewmayer
2ω=0
 
ewmayer's Avatar
 
Sep 2002
República de California

3·7·13·43 Posts
Default

Not directly related - except in the sense that the array-init question came up while I was doing early prototyping - but a not-terribly-optimized but decently functional bc-based small-p sieve code follows:
Code:
/* returns 1 if p is a base-z Fermat pseudoprime, 0 otherwise. */
define pprimef(p,base) {
	auto n,y,z,flag
	y = 1; n = p-1; z = base;
	while(n) {
		flag = n%2;
		n /= 2;
		if(flag) y = (y*z)%p;
		z = (z*z)%p;
		if(!z) return(0);
	}
	return(y==1);
}

define isprp(p) {
	if(p == 2) return(1);
	if(p%2 == 0) return(0);
	/* Must only use inputs > the largest pprimef-base used below ... better, use that 341 is the smallest base-2 Fermat-pseudoprime: */
	if(p <= 341) { return(pprimef(p,2)) }
	return(pprimef(p,2) && pprimef(p,3) && pprimef(p,5) && pprimef(p,7) && pprimef(p,11) && pprimef(p,13));
}

define trailz(n) {
	auto i
	i = 0
	while(n && (n%2 == 0)) { i += 1; n /= 2; }
	return(i)
}

define bits(n) {
	auto i;
	i = 0;
	while(n) {
		n /= 2;
		i += 1;
	}
	return(i)
}

define reverse(n,nbits) {
	auto tmp;
	tmp = 0;
	while(nbits) {
		tmp = 2*tmp + (n % 2);
		n /= 2;
		nbits -= 1;
	}
	return(tmp);
}

define abs(n) {
	if(n < 0) return(-n);
	return(n);
}
/* Find all prime factors of n which are <= max: */
define trialdiv(n,max) {
	auto i,p,ndiv
	if(max < 2) return(0);	/* Only allow positive small-prime divisors */
	if(abs(n) < 2) return(0);
	ndiv = n;
	i = trailz(ndiv);
	if(i) {
		print "Input ",n," has a small factor: 2^",i,"\n";
		ndiv /= 2^i;
	}
	/* Now loop over odd primes <= max: */
	p = 3;
	while(p <= max && p <= sqrt(ndiv)) {
		i = 0;
		while(ndiv%p == 0) { i++; ndiv/= p; }
		if(i) {
			print p^i*ndiv," has a small factor: ",p,"^",i,"\n";
			if(isprp(ndiv)) {
				print "Remaining cofactor ",ndiv," is prime.\n";
				break;
			}
		}
		/* find next-larger prime (actually, base-2 Fermat-PRP is fine in this context): */
		while(1) {
			p += 2;
			if(pprimef(p,2)) {
				break;
			}
		}
	}
	return(0);
}
I have a bunch of such utils which I plan to port to bc over time, because I am sick of the hassle of finding/building versions of Pari/GP and GMP on my several-years-behind-the-latest version of OS X (FYI, I have good reasons not to 'upgrade'), and I usually don't need it to be super fast, I just need it to !$&$@ work. Had Pari/GP (I think v2.5-something) installed and working on my old Mac hard drive which finally gave up the ghost last month, had such a devil of a time over the weekend trying to find a currently-available version of Pari/GP which will run on my reconstructed system (OS X 10.7) that I was led to consider rolling my own basic stuff in bc, because if I have a Posix-style OS, I know bc will work, even if it's not great.

Now, something like a basic ECM implementation in bc to extend my factoring capability beyond TF - that might be an interesting side project for the coming year.
ewmayer is offline   Reply With Quote
Old 2017-10-11, 00:01   #9
science_man_88
 
science_man_88's Avatar
 
"Forget I exist"
Jul 2009
Dumbassville

203068 Posts
Default

Quote:
Originally Posted by ewmayer View Post
Not directly related - except in the sense that the array-init question came up while I was doing early prototyping - but a not-terribly-optimized but decently functional bc-based small-p sieve code follows:
Code:
/* returns 1 if p is a base-z Fermat pseudoprime, 0 otherwise. */
define pprimef(p,base) {
	auto n,y,z,flag
	y = 1; n = p-1; z = base;
	while(n) {
		flag = n%2;
		n /= 2;
		if(flag) y = (y*z)%p;
		z = (z*z)%p;
		if(!z) return(0);
	}
	return(y==1);
}

define isprp(p) {
	if(p == 2) return(1);
	if(p%2 == 0) return(0);
	/* Must only use inputs > the largest pprimef-base used below ... better, use that 341 is the smallest base-2 Fermat-pseudoprime: */
	if(p <= 341) { return(pprimef(p,2)) }
	return(pprimef(p,2) && pprimef(p,3) && pprimef(p,5) && pprimef(p,7) && pprimef(p,11) && pprimef(p,13));
}

define trailz(n) {
	auto i
	i = 0
	while(n && (n%2 == 0)) { i += 1; n /= 2; }
	return(i)
}

define bits(n) {
	auto i;
	i = 0;
	while(n) {
		n /= 2;
		i += 1;
	}
	return(i)
}

define reverse(n,nbits) {
	auto tmp;
	tmp = 0;
	while(nbits) {
		tmp = 2*tmp + (n % 2);
		n /= 2;
		nbits -= 1;
	}
	return(tmp);
}

define abs(n) {
	if(n < 0) return(-n);
	return(n);
}
/* Find all prime factors of n which are <= max: */
define trialdiv(n,max) {
	auto i,p,ndiv
	if(max < 2) return(0);	/* Only allow positive small-prime divisors */
	if(abs(n) < 2) return(0);
	ndiv = n;
	i = trailz(ndiv);
	if(i) {
		print "Input ",n," has a small factor: 2^",i,"\n";
		ndiv /= 2^i;
	}
	/* Now loop over odd primes <= max: */
	p = 3;
	while(p <= max && p <= sqrt(ndiv)) {
		i = 0;
		while(ndiv%p == 0) { i++; ndiv/= p; }
		if(i) {
			print p^i*ndiv," has a small factor: ",p,"^",i,"\n";
			if(isprp(ndiv)) {
				print "Remaining cofactor ",ndiv," is prime.\n";
				break;
			}
		}
		/* find next-larger prime (actually, base-2 Fermat-PRP is fine in this context): */
		while(1) {
			p += 2;
			if(pprimef(p,2)) {
				break;
			}
		}
	}
	return(0);
}
I have a bunch of such utils which I plan to port to bc over time, because I am sick of the hassle of finding/building versions of Pari/GP and GMP on my several-years-behind-the-latest version of OS X (FYI, I have good reasons not to 'upgrade'), and I usually don't need it to be super fast, I just need it to !$&$@ work. Had Pari/GP (I think v2.5-something) installed and working on my old Mac hard drive which finally gave up the ghost last month, had such a devil of a time over the weekend trying to find a currently-available version of Pari/GP which will run on my reconstructed system (OS X 10.7) that I was led to consider rolling my own basic stuff in bc, because if I have a Posix-style OS, I know bc will work, even if it's not great.

Now, something like a basic ECM implementation in bc to extend my factoring capability beyond TF - that might be an interesting side project for the coming year.
does http://pari.math.u-bordeaux.fr/gp.html not work ?
science_man_88 is offline   Reply With Quote
Old 2017-10-11, 01:30   #10
ewmayer
2ω=0
 
ewmayer's Avatar
 
Sep 2002
República de California

2DDB16 Posts
Default

Quote:
Originally Posted by science_man_88 View Post
Didn't know there was a browser option, but in any case I don't want to have to have an internet pipe open. (I wonder if one could 'save the webpage' and have one's browser store all the underlying code locally - feel free to play around with this.)

I wonder - given essentially the same level of underlying code optimization - which would be faster, pari-via-browser or bc-run-locally-based multiprecision?

UPDATE: Moot in my case - tried a simple 'factor' job of a 64-bit composite in the Pari/GP web app ... first nothing. Enabled JS for the website, that caused something to start loading, but completely locked up my browser (FF) with a "Transferring data from uni.bordeaux.fr..." in the lower-left page-load infospace. Killed FF from a shell, reopened, retried, same locking-up occurred. One more application flunks the ewmayer "I just want it to !^*&$@% work" ease-of-use criterion.

Last fiddled with by ewmayer on 2017-10-11 at 01:42
ewmayer is offline   Reply With Quote
Old 2017-10-11, 02:24   #11
bgbeuning
 
Dec 2014

FF16 Posts
Default

Quote:
Originally Posted by ewmayer View Post
I wonder - given essentially the same level of underlying code optimization - which would be faster, pari-via-browser or bc-run-locally-based multiprecision?
bc seems to be doing base 10 arithmetic.
gmp and most "advanced" packages do base 2^32 (or close) arithmetic.
bgbeuning is offline   Reply With Quote
Reply

Thread Tools


Similar Threads
Thread Thread Starter Forum Replies Last Post
Array vs Hash Table vs Map for QS Sam Kennedy Programming 1 2012-12-25 23:25
Init.d Script for MPrime CrashM Software 0 2012-05-18 01:01
array of bits Citrix Programming 2 2005-08-21 20:06
Ubasic Array question rn0dal Programming 6 2004-09-15 14:57

All times are UTC. The time now is 12:11.


Wed Aug 10 12:11:29 UTC 2022 up 34 days, 6:58, 2 users, load averages: 0.94, 1.09, 1.15

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.

This forum has received and complied with 0 (zero) government requests for information.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation.
A copy of the license is included in the FAQ.

≠ ± ∓ ÷ × · − √ ‰ ⊗ ⊕ ⊖ ⊘ ⊙ ≤ ≥ ≦ ≧ ≨ ≩ ≺ ≻ ≼ ≽ ⊏ ⊐ ⊑ ⊒ ² ³ °
∠ ∟ ° ≅ ~ ‖ ⟂ ⫛
≡ ≜ ≈ ∝ ∞ ≪ ≫ ⌊⌋ ⌈⌉ ∘ ∏ ∐ ∑ ∧ ∨ ∩ ∪ ⨀ ⊕ ⊗ 𝖕 𝖖 𝖗 ⊲ ⊳
∅ ∖ ∁ ↦ ↣ ∩ ∪ ⊆ ⊂ ⊄ ⊊ ⊇ ⊃ ⊅ ⊋ ⊖ ∈ ∉ ∋ ∌ ℕ ℤ ℚ ℝ ℂ ℵ ℶ ℷ ℸ 𝓟
¬ ∨ ∧ ⊕ → ← ⇒ ⇐ ⇔ ∀ ∃ ∄ ∴ ∵ ⊤ ⊥ ⊢ ⊨ ⫤ ⊣ … ⋯ ⋮ ⋰ ⋱
∫ ∬ ∭ ∮ ∯ ∰ ∇ ∆ δ ∂ ℱ ℒ ℓ
𝛢𝛼 𝛣𝛽 𝛤𝛾 𝛥𝛿 𝛦𝜀𝜖 𝛧𝜁 𝛨𝜂 𝛩𝜃𝜗 𝛪𝜄 𝛫𝜅 𝛬𝜆 𝛭𝜇 𝛮𝜈 𝛯𝜉 𝛰𝜊 𝛱𝜋 𝛲𝜌 𝛴𝜎𝜍 𝛵𝜏 𝛶𝜐 𝛷𝜙𝜑 𝛸𝜒 𝛹𝜓 𝛺𝜔