Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add BigInt support to Lisp #415

Merged
merged 51 commits into from
Oct 17, 2022
Merged

Add BigInt support to Lisp #415

merged 51 commits into from
Oct 17, 2022

Conversation

vinc
Copy link
Owner

@vinc vinc commented Oct 1, 2022

  • Add num-bigint crate
  • Add Number enum for BigInt, i64, and f64
  • Add overflow from i64 to BigInt
  • Add example of pi computation

@vinc
Copy link
Owner Author

vinc commented Oct 1, 2022

The code result in an allocation error:

> lisp
MOROS Lisp v0.4.0

> (+ 1 2 3)
Error: Could not allocate address 0xfffffffff8
DEBUG: panicked at 'explicit panic', src/sys/idt.rs:121:13

@vinc
Copy link
Owner Author

vinc commented Oct 1, 2022

The next step after getting this to work will be to start with Number::Int by default and use Number::Float when the parser detect a dot in a number like 1.5 or when one of the argument of an operation is a Number::Float like (+ 1 2 3.5) resulting in 6.5.

Another step would be to use i64 for Number::Int and add Number::BigInt.

One issue will be to handle the overflowing conversion of a big integer into a float, resulting in Inf

@vinc
Copy link
Owner Author

vinc commented Oct 1, 2022

Parsing a &str into a BigInt result in the following linker error:

  = note: rust-lld: error: undefined symbol: fmod
          >>> referenced by num_bigint.01a97d26-cgu.3
          >>>               num_bigint-e7ac2962d814313a.num_bigint.01a97d26-cgu.3.rcgu.o:(num_bigint::biguint::convert::from_radix_digits_be::h7271e1decf7a3dd9) in archive /home/v/src/vinc/moros/target/x86_64-moros/release/deps/libnum_bigint-e7ac2962d814313a.rlib

@vinc
Copy link
Owner Author

vinc commented Oct 1, 2022

Some issues with leading and trailing zeros:

> 1234567890
1234567890

> 1234567890123456789
1234567890123456789

> 12345678901234567890
1234567890123456789

> 123456789012345678900
1234567890123456789

> 1234567890123456789000
1234567890123456789

> 12345678901234567890001
12345678901234567890001

> 0000000111111111111111111111111111111111111111111
0000000111111111111111111111111111111111111111111

@vinc
Copy link
Owner Author

vinc commented Oct 1, 2022

> lisp /tmp/lisp/factorial.lsp 1000
40238726007709377354370243392300398571937486421071463254379991042993851239862902
05920442084869694048004799886101971960586316668729948085589013238296699445909974
24504087073759918823627727188732519779505950995276120874975462497043601418278094
64649629105639388743788648733711918104582578364784997701247663288983595573543251
31853239584630755574091142624174743493475534286465766116677973966688202912073791
43853719588249808126867838374559731746136085379534524221586593201928090878297308
43139284440328123155861103697680135730421616874760967587134831202547858932076716
91324484262361314125087802080002616831510273418279777047846358681701643650241536
91398281264810213092761244896359928705114964975419909342221566832572080821333186
11681155361583654698404670897560290095053761647584772842188967964624494516076535
34081989013854424879849599533191017233555566021394503997362807501378376153071277
61926849034352625200015888535147331611702103968175921510907788019393178114194545
25722386554146106289218796022383897147608850627686296714667469756291123408243920
81601537808898939645182632436716167621791689097799119037540312746222899880051954
44414282012187361745992642956581746628302955570299024324153181617210465832036786
90611726015878352075151628422554026517048330422614397428693306169089796848259012
54583271682264580665267699586526822728070757813918581788896522081643483448259932
66043367660176999612831860788386150279465955131156552036093988180612138558600301
43569452722420634463179746059468257310379008402443243846565724501440282188525247
09351906209290231364932734975655139587205596542287497740114133469627154228458623
77387538230483865688976461927383814900140767310446640259899490222221765904339901
88601856652648506179970235619389701786004081188972991831102117122984590164192106
88843871218556461249607987229085192968193723886426148396573822911231250241866493
53143970137428531926649875337218940694281434118520158014123344828015051399694290
15348307764456909907315243327828826986460278986432113908350621709500259738986355
42771967428222487575867657523442202075736305694988250879689281627538488633969099
59826280956121450994871701244516461260379029309120889086942028510640182154399457
15680594187274899809425474217358240106367740459574178516082923013535808184009699
63725242305608559037006242712434169090041536901059339838357779394109700277534720
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000

@vinc
Copy link
Owner Author

vinc commented Oct 2, 2022

> (map (fn (x) (println (string "2 ^ " x " = " (^ 2 x)))) (range 0 129))
2 ^ 128 = 340282366920938463463374607431768211456
2 ^ 127 = 170141183460469231731687303715884105728
2 ^ 126 = 85070591730234615865843651857942052864
2 ^ 125 = 42535295865117307932921825928971026432
2 ^ 124 = 21267647932558653966460912964485513216
2 ^ 123 = 10633823966279326983230456482242756608
2 ^ 122 = 5316911983139663491615228241121378304
2 ^ 121 = 2658455991569831745807614120560689152
2 ^ 120 = 1329227995784915872903807060280344576
2 ^ 119 = 664613997892457936451903530140172288
2 ^ 118 = 332306998946228968225951765070086144
2 ^ 117 = 166153499473114484112975882535043072
2 ^ 116 = 83076749736557242056487941267521536
2 ^ 115 = 41538374868278621028243970633760768
2 ^ 114 = 20769187434139310514121985316880384
2 ^ 113 = 10384593717069655257060992658440192
2 ^ 112 = 5192296858534827628530496329220096
2 ^ 111 = 2596148429267413814265248164610048
2 ^ 110 = 1298074214633706907132624082305024
2 ^ 109 = 649037107316853453566312041152512
2 ^ 108 = 324518553658426726783156020576256
2 ^ 107 = 162259276829213363391578010288128
2 ^ 106 = 81129638414606681695789005144064
2 ^ 105 = 40564819207303340847894502572032
2 ^ 104 = 20282409603651670423947251286016
2 ^ 103 = 10141204801825835211973625643008
2 ^ 102 = 5070602400912917605986812821504
2 ^ 101 = 2535301200456458802993406410752
2 ^ 100 = 1267650600228229401496703205376
2 ^ 99 = 633825300114114700748351602688
2 ^ 98 = 316912650057057350374175801344
2 ^ 97 = 158456325028528675187087900672
2 ^ 96 = 79228162514264337593543950336
2 ^ 95 = 39614081257132168796771975168
2 ^ 94 = 19807040628566084398385987584
2 ^ 93 = 9903520314283042199192993792
2 ^ 92 = 4951760157141521099596496896
2 ^ 91 = 2475880078570760549798248448
2 ^ 90 = 1237940039285380274899124224
2 ^ 89 = 618970019642690137449562112
2 ^ 88 = 309485009821345068724781056
2 ^ 87 = 154742504910672534362390528
2 ^ 86 = 77371252455336267181195264
2 ^ 85 = 38685626227668133590597632
2 ^ 84 = 19342813113834066795298816
2 ^ 83 = 9671406556917033397649408
2 ^ 82 = 4835703278458516698824704
2 ^ 81 = 2417851639229258349412352
2 ^ 80 = 1208925819614629174706176
2 ^ 79 = 604462909807314587353088
2 ^ 78 = 302231454903657293676544
2 ^ 77 = 151115727451828646838272
2 ^ 76 = 75557863725914323419136
2 ^ 75 = 37778931862957161709568
2 ^ 74 = 18889465931478580854784
2 ^ 73 = 9444732965739290427392
2 ^ 72 = 4722366482869645213696
2 ^ 71 = 2361183241434822606848
2 ^ 70 = 1180591620717411303424
2 ^ 69 = 590295810358705651712
2 ^ 68 = 295147905179352825856
2 ^ 67 = 147573952589676412928
2 ^ 66 = 73786976294838206464
2 ^ 65 = 36893488147419103232
2 ^ 64 = 18446744073709551616
2 ^ 63 = 9223372036854775808
2 ^ 62 = 4611686018427387904
2 ^ 61 = 2305843009213693952
2 ^ 60 = 1152921504606846976
2 ^ 59 = 576460752303423488
2 ^ 58 = 288230376151711744
2 ^ 57 = 144115188075855872
2 ^ 56 = 72057594037927936
2 ^ 55 = 36028797018963968
2 ^ 54 = 18014398509481984
2 ^ 53 = 9007199254740992
2 ^ 52 = 4503599627370496
2 ^ 51 = 2251799813685248
2 ^ 50 = 1125899906842624
2 ^ 49 = 562949953421312
2 ^ 48 = 281474976710656
2 ^ 47 = 140737488355328
2 ^ 46 = 70368744177664
2 ^ 45 = 35184372088832
2 ^ 44 = 17592186044416
2 ^ 43 = 8796093022208
2 ^ 42 = 4398046511104
2 ^ 41 = 2199023255552
2 ^ 40 = 1099511627776
2 ^ 39 = 549755813888
2 ^ 38 = 274877906944
2 ^ 37 = 137438953472
2 ^ 36 = 68719476736
2 ^ 35 = 34359738368
2 ^ 34 = 17179869184
2 ^ 33 = 8589934592
2 ^ 32 = 4294967296
2 ^ 31 = 2147483648
2 ^ 30 = 1073741824
2 ^ 29 = 536870912
2 ^ 28 = 268435456
2 ^ 27 = 134217728
2 ^ 26 = 67108864
2 ^ 25 = 33554432
2 ^ 24 = 16777216
2 ^ 23 = 8388608
2 ^ 22 = 4194304
2 ^ 21 = 2097152
2 ^ 20 = 1048576
2 ^ 19 = 524288
2 ^ 18 = 262144
2 ^ 17 = 131072
2 ^ 16 = 65536
2 ^ 15 = 32768
2 ^ 14 = 16384
2 ^ 13 = 8192
2 ^ 12 = 4096
2 ^ 11 = 2048
2 ^ 10 = 1024
2 ^ 9 = 512
2 ^ 8 = 256
2 ^ 7 = 128
2 ^ 6 = 64
2 ^ 5 = 32
2 ^ 4 = 16
2 ^ 3 = 8
2 ^ 2 = 4
2 ^ 1 = 2
2 ^ 0 = 1

@vinc
Copy link
Owner Author

vinc commented Oct 2, 2022

> (/ 1 0)
Error: Division by zero

> (/ 1 0.0)
Error: Division by zero

> (/ 1111111111111111111111111111111111111111 0)
Error: Division by zero

@vinc
Copy link
Owner Author

vinc commented Oct 13, 2022

The shell builtin pi command can display any number of digits without issues:

> pi 500
3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912

But the lisp version can't run much more than 500 iterations of the algorithm (not digits) without running into memory issues with 32MB:

> lisp /tmp/lisp/pi.lsp 500
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282303

> lisp /tmp/lisp/pi.lsp 600
DEBUG: panicked at 'allocation error: Layout { size: 10080, align: 8 (1 << 3) }', src/lib.rs:46:5

It's a little bit better when we increase the memory but we then run into other issues like slice index larger than 2^64

@vinc vinc changed the title Add bigint support to Lisp Add BigInt support to Lisp Oct 13, 2022
@vinc vinc marked this pull request as ready for review October 17, 2022 18:57
@vinc vinc merged commit 892b697 into trunk Oct 17, 2022
@vinc vinc deleted the feature/lisp-bigint branch November 13, 2022 18:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant