Mainframes were always large and impressive, something the credit card sized Raspberry Pi cannot compete with despite being more powerful!Heater wrote: ↑Thu Jun 13, 2019 10:00 amAwesome.
I was there the day they delivered a new ICL 2960 to our uni CS department. A few giant trucks turned up. They laid down an aluminium plate road way from the trucks into the building. Then rolled out a lot of very big sexy looking bright orange boxes, drives, processor, etc. Most impressive.
I used to work in a 21000 square foot datacentre with a large mainframe. That got replaced by a PC sitting under a desk running emulation software. The tape drives were replaced by a Unix box with a load of disks and a tape autoloader for long term storage. The banks of modems were replaced by another Unix box with an Ethernet link. The only things that stayed were the high speed printers (3000 pages in 10-15 minutes)jahboater wrote: ↑Thu Jun 13, 2019 10:08 amMainframes were always large and impressive, something the credit card sized Raspberry Pi cannot compete with despite being more powerful!Heater wrote: ↑Thu Jun 13, 2019 10:00 amAwesome.
I was there the day they delivered a new ICL 2960 to our uni CS department. A few giant trucks turned up. They laid down an aluminium plate road way from the trucks into the building. Then rolled out a lot of very big sexy looking bright orange boxes, drives, processor, etc. Most impressive.
I once worked at BRA01 a large ICL building. Most of the ground floor was the machine hall for the mainframes, the largest in Europe, with a raised viewing gallery all around the edge which took a long time to walk around. Over the years more and more of the hall was converted to offices as mainframes got smaller.
It's by definition.ScriptBasic wrote: ↑Thu Jun 13, 2019 1:59 pmIs t hat a guess or did you try running it and noticed the leak?
If you are talking about C then it is simple (though it may not appear so!)ScriptBasic wrote: ↑Thu Jun 13, 2019 2:58 pmIf it is leaking, I can add a static function to do the clear before exiting the function. It's always been a mystery what is freed when exiting a function and what manually needs to be freed. Strings seem to be the major concern.
Code: Select all
foo( void )
{
char *ptr = malloc(42);
}
It's got me mystified, how one can concatenate strings and return that from a function -
Code: Select all
char * GetErrorMessage(int n)
{
char * errorMessage = ConcatenateStrings("Error ", intToString(n));
return errorMessage;
}
That looks fine!hippy wrote: ↑Thu Jun 13, 2019 3:17 pmIt's got me mystified, how one can concatenate strings and return that from a function -Probably off topic for this thread.Code: Select all
char * GetErrorMessage(int n) { char * errorMessage = ConcatenateStrings("Error is: ", intToString(n)); return errorMessage; }
Code: Select all
int * foo( void )
{
int num = 42;
int *ptr = #
return ptr;
}
It may be time for an emulated Fibonacci roundup that includes Algol, PL/I, Basic and other languages running in emulators on the Raspberry Pi.PeterO wrote: ↑Thu Jun 13, 2019 11:10 amI forgot to add the link to the George 3 Emulator if anyone wants to try it... It's quite a challenge to get anything done though
https://www.icl1900.co.uk/preserve/g3ee.html
PeterO
Code: Select all
/* GMP Extension Module
UXLIBS: -lc -lgmp
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <gmp.h>
#include "../../basext.h"
static mpz_t op1;
static mpz_t op2;
static mpz_t res;
static void gmp_clear(void){
mpz_clear(op1);
mpz_clear(op2);
mpz_clear(res);
return 0;
}
/**************************
Extension Module Functions
**************************/
typedef struct _ModuleObject {
void *HandleArray;
}ModuleObject,*pModuleObject;
besVERSION_NEGOTIATE
return (int)INTERFACE_VERSION;
besEND
besSUB_START
pModuleObject p;
besMODULEPOINTER = besALLOC(sizeof(ModuleObject));
if( besMODULEPOINTER == NULL )return 0;
p = (pModuleObject)besMODULEPOINTER;
return 0;
besEND
besSUB_FINISH
pModuleObject p;
p = (pModuleObject)besMODULEPOINTER;
if( p == NULL )return 0;
return 0;
besEND
/*************
GMP Functions
*************/
besFUNCTION(fibo)
int fval;
besARGUMENTS("i")
&fval
besARGEND
char buf[1500000];
memset(buf,0,1);
mpz_init(res);
mpz_fib_ui(res, fval);
gmp_snprintf( buf,sizeof(buf),"%Zd", res );
mpz_clear(res);
besRETURN_STRING(buf);
besEND
besFUNCTION(bi_add)
const char* s1;
const char* s2;
besARGUMENTS("zz")
&s1, &s2
besARGEND
char buf[1500000];
memset(buf,0,1);
mpz_init(op1);
mpz_init(op2);
mpz_set_str(op1, s1, 10);
mpz_set_str(op2, s2, 10);
mpz_init(res);
mpz_add(res, op1, op2);
gmp_snprintf(buf, sizeof(buf), "%Zd", res);
gmp_clear();
besRETURN_STRING(buf);
besEND
besFUNCTION(bi_sub)
const char* s1;
const char* s2;
besARGUMENTS("zz")
&s1, &s2
besARGEND
char buf[1500000];
memset(buf,0,1);
mpz_init(op1);
mpz_init(op2);
mpz_set_str(op1, s1, 10);
mpz_set_str(op2, s2, 10);
mpz_init(res);
mpz_sub (res, op1, op2);
gmp_snprintf(buf, sizeof(buf), "%Zd", res);
gmp_clear();
besRETURN_STRING(buf);
besEND
besFUNCTION(bi_mul)
const char* s1;
const char* s2;
besARGUMENTS("zz")
&s1, &s2
besARGEND
char buf[1500000];
memset(buf,0,1);
mpz_init(op1);
mpz_init(op2);
mpz_set_str(op1, s1, 10);
mpz_set_str(op2, s2, 10);
mpz_init(res);
mpz_mul (res, op1, op2);
gmp_snprintf(buf, sizeof(buf), "%Zd", res);
gmp_clear();
besRETURN_STRING(buf);
besEND
Code: Select all
DECLARE SUB BI_ADD ALIAS "bi_add" LIB "gmp"
FUNCTION sfibo (n)
IF n < 2 THEN
sfibo = 1
ELSE
m = 0
p = 1
q = 0
FOR i = 2 TO n
m = BI_ADD(p, q)
q = p
p = m
NEXT i
sfibo = m
END IF
END FUNCTION
PRINT sfibo(78000),"\n"
Code: Select all
jrs@jrs-laptop:~/sb/GMP$ time scriba sfibo.sb > sfibo.out
real 0m44.118s
user 0m43.093s
sys 0m0.937s
jrs@jrs-laptop:~/sb/GMP$ ls -l sfibo.out
-rw-r--r-- 1 jrs jrs 16302 Jun 13 12:23 sfibo.out
jrs@jrs-laptop:~/sb/GMP$ tail -c64 sfibo.out
840773259352868233566983589379711278754520073189001074454696000
jrs@jrs-laptop:~/sb/GMP$
Code: Select all
Usage: python fibo_final.py [options] [index]
or
python3 fibo_final.py [options] [index]
or
pypy fibo_final.py [options] [index]
Note: pypy cannot use gmpy2
index: Fibonacci number to be calculated, default = 4784969
Options:
-t don't print result, only time needed for Fibonacci calculation and string conversion
-n don't convert result to string in timing mode
-i use Python internal BIGINTS, even if gmpy2 is installed
-c cheat = use GMP's internal Fibonacci function if possible
-h, --help print this text
Code: Select all
pi@raspberrypi4:~ $ time python fibo_final.py | tail -c 32
4856539211500699706378405156269
real 0m1,795s
user 0m1,732s
sys 0m0,042s
pi@raspberrypi4:~ $ python fibo_final.py -t
Fibonacci calculation took 0.42829990387 seconds
String conversion took 1.28486704826 seconds
Fibonacci Number has 1000000 digits
Fibonacci calculation needed 59 recursive calculations
pi@raspberrypi4:~ $ python3 fibo_final.py -t -c
Fibonacci calculation took 0.26346707344055176 seconds
String conversion took 1.265275478363037 seconds
Fibonacci Number has 1000000 digits
pi@raspberrypi4:~ $ python fibo_final.py -t 10000000
Fibonacci calculation took 0.814356803894 seconds
String conversion took 3.36349606514 seconds
Fibonacci Number has 2089877 digits
Fibonacci calculation needed 56 recursive calculations
pi@raspberrypi4:~ $ pypy fibo_final.py -t
Fibonacci calculation took 6.37379097939 seconds
String conversion took 75.8342139721 seconds
Fibonacci Number has 1000000 digits
Fibonacci calculation needed 59 recursive calculations
pi@raspberrypi4:~ $ python3 fibo_final.py -t -i -n
Fibonacci calculation took 10.611706018447876 seconds
Fibonacci calculation needed 59 recursive calculations
Code: Select all
## Fibonacci challenge script fibo_final.py
import time, sys
use_gmp = True
use_gmp_fibo = False
timing_only = False
string_conversion = True
fibs = {0:0, 1:1, 2:1}
index = 4784969
usage = '''Usage: python fibo_final.py [options] [index]
or
python3 fibo_final.py [options] [index]
or
pypy fibo_final.py [options] [index]
Note: pypy cannot use gmpy2
index: Fibonacci number to be calculated, default = 4784969
Options:
-t don't print result, only timing for Fibonacci calculation and string conversion
-n don't convert result to string in timing mode
-i use Python internal BIGINTS, even if gmpy2 is installed
-c cheat = use GMP's internal Fibonacci function if possible
-h, --help print this text
'''
def fibo(n):
if n in fibs:
return fibs[n]
k = (n + 1) // 2
fk = fibo(k)
fk1 = fibo(k - 1)
if n & 1:
result = fk ** 2 + fk1 ** 2
else:
result = (2 * fk1 + fk) * fk
fibs[n] = result
return result
if len(sys.argv) > 1:
for arg in sys.argv[1:]:
if arg in ['-h','--help']:
print(usage)
sys.exit(0)
if arg in ['-t', '-i', '-c', '-n']:
if arg == '-t':
timing_only = True
elif arg == '-i':
use_gmp = False
elif arg == '-c':
use_gmp_fibo = True
elif arg == '-n':
string_conversion = False
else:
try:
index = int(arg)
except:
pass
if use_gmp:
try:
import gmpy2
from gmpy2 import mpz
fibs = {0:mpz(0), 1:mpz(1), 2:mpz(1)}
except:
use_gmp = False
use_gmp_fibo = False
if timing_only:
if use_gmp and use_gmp_fibo:
t = time.time()
res = gmpy2.fib(index)
fibt = time.time()-t
else:
t = time.time()
res = fibo(index)
fibt = time.time()-t
if string_conversion:
t = time.time()
restr = str(res)
strcvt = time.time()-t
print('Fibonacci('+str(index)+') calculation took '+str(fibt)+' seconds')
if string_conversion:
print('String conversion took '+str(strcvt)+' seconds')
print('Fibonacci Number has '+str(len(restr))+' digits')
if not use_gmp_fibo:
print(str(len(fibs)-3) + ' Fibonacci numbers have been calculated')
else:
if use_gmp_fibo:
print(gmpy2.fib(index))
else:
print(fibo(index))
Code: Select all
/* GMP Extension Module
UXLIBS: -lc -lgmp
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <gmp.h>
#include "../../basext.h"
static mpz_t op1;
static mpz_t op2;
static mpz_t res;
static void gmp_clear(void){
mpz_clear(op1);
mpz_clear(op2);
mpz_clear(res);
return 0;
}
static void gmp_init(void){
mpz_init(op1);
mpz_init(op2);
mpz_init(res);
return 0;
}
/**************************
Extension Module Functions
**************************/
typedef struct _ModuleObject {
void *HandleArray;
}ModuleObject,*pModuleObject;
besVERSION_NEGOTIATE
return (int)INTERFACE_VERSION;
besEND
besSUB_START
pModuleObject p;
besMODULEPOINTER = besALLOC(sizeof(ModuleObject));
if( besMODULEPOINTER == NULL )return 0;
p = (pModuleObject)besMODULEPOINTER;
return 0;
besEND
besSUB_FINISH
pModuleObject p;
p = (pModuleObject)besMODULEPOINTER;
if( p == NULL )return 0;
return 0;
besEND
/*************
GMP Functions
*************/
besFUNCTION(fibo)
int fval;
besARGUMENTS("i")
&fval
besARGEND
char buf[1500000];
memset(buf,0,1);
mpz_init(res);
mpz_fib_ui(res, fval);
gmp_snprintf( buf,sizeof(buf),"%Zd", res );
mpz_clear(res);
besRETURN_STRING(buf);
besEND
besFUNCTION(bi_add)
const char* s1;
const char* s2;
besARGUMENTS("zz")
&s1, &s2
besARGEND
char buf[1500000];
memset(buf,0,1);
gmp_init();
mpz_set_str(op1, s1, 10);
mpz_set_str(op2, s2, 10);
mpz_add(res, op1, op2);
gmp_snprintf(buf, sizeof(buf), "%Zd", res);
gmp_clear();
besRETURN_STRING(buf);
besEND
besFUNCTION(bi_sub)
const char* s1;
const char* s2;
besARGUMENTS("zz")
&s1, &s2
besARGEND
char buf[1500000];
memset(buf,0,1);
gmp_init();
mpz_set_str(op1, s1, 10);
mpz_set_str(op2, s2, 10);
mpz_sub (res, op1, op2);
gmp_snprintf(buf, sizeof(buf), "%Zd", res);
gmp_clear();
besRETURN_STRING(buf);
besEND
besFUNCTION(bi_mul)
const char* s1;
const char* s2;
besARGUMENTS("zz")
&s1, &s2
besARGEND
char buf[1500000];
memset(buf,0,1);
gmp_init();
mpz_set_str(op1, s1, 10);
mpz_set_str(op2, s2, 10);
mpz_mul (res, op1, op2);
gmp_snprintf(buf, sizeof(buf), "%Zd", res);
gmp_clear();
besRETURN_STRING(buf);
besEND
I suggest the "tdiv" functions for truncating integer division (that is, they truncate towards zero like normal hardware integer divide works). mpz_tdiv_q() etc.ScriptBasic wrote: ↑Thu Jun 13, 2019 11:28 pmCan someone suggest what GMP divide function would be best. There seems to be a few options for the operator.
Code: Select all
function isEven(n) {
return (n & 1) === 0;
}
let memo = [BigInt(0), BigInt(1), BigInt(1)]
//
// This is a fast and big Fibonacci number calculator based on the suggestions here:
// https://www.nayuki.io/page/fast-fibonacci-algorithms
//
function fibo (n) {
if (typeof memo[n] != 'undefined') {
return memo[n]
}
let k = Math.floor(n / 2)
let a = fibo(k);
let b = fibo(k + 1);
if (isEven(n)) {
return memo[n] = a * ((b * 2n) - a)
}
return memo[n] = a ** 2n + b ** 2n
}
Code: Select all
/* GMP Extension Module
UXLIBS: -lc -lgmp
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <gmp.h>
#include "../../basext.h"
static mpz_t op1;
static mpz_t op2;
static mpz_t res;
static void gmp_clear(void){
mpz_clear(op1);
mpz_clear(op2);
mpz_clear(res);
}
static void gmp_init(void){
mpz_init(op1);
mpz_init(op2);
mpz_init(res);
}
/**************************
Extension Module Functions
**************************/
typedef struct _ModuleObject {
void *HandleArray;
}ModuleObject,*pModuleObject;
besVERSION_NEGOTIATE
return (int)INTERFACE_VERSION;
besEND
besSUB_START
pModuleObject p;
besMODULEPOINTER = besALLOC(sizeof(ModuleObject));
if( besMODULEPOINTER == NULL )return 0;
p = (pModuleObject)besMODULEPOINTER;
return 0;
besEND
besSUB_FINISH
pModuleObject p;
p = (pModuleObject)besMODULEPOINTER;
if( p == NULL )return 0;
return 0;
besEND
/*************
GMP Functions
*************/
besFUNCTION(fibo)
int fval;
besARGUMENTS("i")
&fval
besARGEND
char buf[1500000];
memset(buf,0,1);
mpz_init(res);
mpz_fib_ui(res, fval);
gmp_snprintf( buf,sizeof(buf),"%Zd", res );
mpz_clear(res);
besRETURN_STRING(buf);
besEND
besFUNCTION(bi_add)
const char* s1;
const char* s2;
besARGUMENTS("zz")
&s1, &s2
besARGEND
gmp_init();
mpz_set_str(op1, s1, 10);
mpz_set_str(op2, s2, 10);
mpz_add(res, op1, op2);
char* res_string = mpz_get_str (0, 10, res);
besSET_RETURN_STRING(res_string);
gmp_clear();
free(res_string);
besEND
besFUNCTION(bi_sub)
const char* s1;
const char* s2;
besARGUMENTS("zz")
&s1, &s2
besARGEND
gmp_init();
mpz_set_str(op1, s1, 10);
mpz_set_str(op2, s2, 10);
mpz_sub (res, op1, op2);
char* res_string = mpz_get_str (0, 10, res);
besSET_RETURN_STRING(res_string);
gmp_clear();
free(res_string);
besEND
besFUNCTION(bi_mul)
const char* s1;
const char* s2;
besARGUMENTS("zz")
&s1, &s2
besARGEND
gmp_init();
mpz_set_str(op1, s1, 10);
mpz_set_str(op2, s2, 10);
mpz_mul (res, op1, op2);
char* res_string = mpz_get_str (0, 10, res);
besSET_RETURN_STRING(res_string);
gmp_clear();
free(res_string);
besEND
Code: Select all
DECLARE SUB BI_ADD ALIAS "bi_add" LIB "gmp"
DECLARE SUB BI_SUB ALIAS "bi_sub" LIB "gmp"
DECLARE SUB BI_MUL ALIAS "bi_mul" LIB "gmp"
a = 123456789
b = 987654321
c = a * b
PRINT c,"\n"
PRINT BI_MUL(c, STRREVERSE(c)),"\n"
Code: Select all
jrs@jrs-laptop:~/sb/GMP$ scriba gmpmul.sb
121932631112635269
117364572765028660532228440042158549
jrs@jrs-laptop:~/sb/GMP$
That is cool an all. I guess we may not have commented on this use of numbers and strings together if it were not a regular thing we can do in man other languages .Why I like this GMP interface.
Notice how JS gives the "wrong" answer for 1111 + "1111" and "1111" + 1111. Well of course, the + operator is used as a nice simple string concatenation operator, so that's what it does here having converted the numbers to strings. Conversely -, *, / don't make any obvious sense for strings so they are used as maths operations after converting the strings to numbers.> 1111 + 1111
2222
> 1111 - 1111
0
> 1111 * 1111
1234321
> 1111 / 1111
1
> 1111 + "1111"
'11111111'
> 1111 - "1111"
0
> 1111 * "1111"
1234321
> 1111 / "1111"
1
> "1111" + 1111
'11111111'
> "1111" - 1111
0
> "1111" * 1111
1234321
> "1111" / 1111
1
> "1111" + "1111"
'11111111'
> "1111" - "1111"
0
> "1111" * "1111"
1234321
> "1111" / "1111"
1
Code: Select all
mpz_add(res, op1, op2);
char* res_string = mpz_get_str (0, 10, res);
besSET_RETURN_STRING(res_string);
gmp_clear();
free(res_string);
Code: Select all
int
main (void)
{
mpz_class a, b, c;
a = 1234;
b = "-5678";
c = a+b;
cout << "sum is " << c << "\n";
cout << "absolute value is " << abs(c) << "\n";
return 0;
}
The price of seamless integration.,That a lot of redundant memory allocation and copying going on.
The C++ integration which looks very seamless, doesn't do all that (see the example and link in my previous post).ScriptBasic wrote: ↑Fri Jun 14, 2019 6:54 amThe price of seamless integration.,That a lot of redundant memory allocation and copying going on.![]()