From d703a6f20df15b753cc4f674afdaf79b74853a8c Mon Sep 17 00:00:00 2001 From: Saurabh Kumar <151380951+kmr-srbh@users.noreply.github.com> Date: Sat, 17 Feb 2024 11:34:41 +0530 Subject: [PATCH 1/7] Added `flex` and `zstd-static=1.5.5` packages. --- environment_win.yml | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/environment_win.yml b/environment_win.yml index af80e30c7c..3da9d77cac 100644 --- a/environment_win.yml +++ b/environment_win.yml @@ -2,18 +2,20 @@ name: lp channels: - conda-forge dependencies: - - python=3.10.2 - - numpy - - flake8 + - git - pip + - make + - re2c - toml + - zlib + - flex + - cmake + - ninja + - numpy + - xonsh + - flake8 - setuptools - - llvmdev=11.1.0 + - python=3.10.2 - m2-bison=3.0.4 - - re2c - - xonsh - - ninja - - cmake - - make - - zlib - - git + - llvmdev=11.1.0 + - zstd-static=1.5.5 From c5731b73db72613b24f8537114fe83b3da9a2edb Mon Sep 17 00:00:00 2001 From: Saurabh Kumar <151380951+kmr-srbh@users.noreply.github.com> Date: Sat, 17 Feb 2024 11:35:24 +0530 Subject: [PATCH 2/7] Added `flex` and `zstd-static=1.5.5` packages. --- environment_unix.yml | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/environment_unix.yml b/environment_unix.yml index 0942bbcbaf..ddea38dd0b 100644 --- a/environment_unix.yml +++ b/environment_unix.yml @@ -2,16 +2,18 @@ name: lp channels: - conda-forge dependencies: - - bison=3.4 - - cmake - - flake8 - - llvmdev=11.0.1 - - make - - numpy + - git - pip - - python=3.10.2 + - make - re2c - - setuptools - toml - zlib - - git + - flex + - cmake + - numpy + - flake8 + - setuptools + - bison=3.4 + - python=3.10.2 + - llvmdev=11.0.1 + - zstd-static=1.5.5 From 433e4af2faa64d0d89166bde4bfdc65f21dd9e05 Mon Sep 17 00:00:00 2001 From: Saurabh Kumar <151380951+kmr-srbh@users.noreply.github.com> Date: Sat, 17 Feb 2024 11:37:57 +0530 Subject: [PATCH 3/7] Incorporated suggestions from #2537 Moved global package installations to conda environment. --- doc/src/installation.md | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/doc/src/installation.md b/doc/src/installation.md index e9db50cf92..bc02241cab 100644 --- a/doc/src/installation.md +++ b/doc/src/installation.md @@ -12,16 +12,10 @@ Follow the steps below to install and run LPython on Linux, Windows or macOS. - ### Set up your system - Linux - - Make sure you have `g++` and `cmake` installed. If not, install them using the below command: + - Run the following command to install some global build dependencies: ```bash - sudo apt-get install g++ cmake - ``` - - - Run the following command to install the build dependencies: - - ```bash - sudo apt-get install binutils-dev build-essential zlib1g-dev bison re2c flex + sudo apt-get install build-essential binutils-dev clang zlib1g-dev ``` - Windows - Download and install [Microsoft Visual Studio Community](https://visualstudio.microsoft.com/downloads/) for free. From bfa0cdeebd68e40840ffffec3953bb1591be479b Mon Sep 17 00:00:00 2001 From: Saurabh Kumar <151380951+kmr-srbh@users.noreply.github.com> Date: Sat, 17 Feb 2024 11:41:53 +0530 Subject: [PATCH 4/7] Updated README.md to reflect changes suggested in #2537 --- README.md | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 49502b582f..6324f41306 100644 --- a/README.md +++ b/README.md @@ -36,16 +36,10 @@ Follow the steps below to install and run LPython on Linux, Windows or macOS. - ### Set up your system - Linux - - Make sure you have `g++` and `cmake` installed. If not, install them using the below command: + - Run the following command to install some global build dependencies: ```bash - sudo apt-get install g++ cmake - ``` - - - Run the following command to install the build dependencies: - - ```bash - sudo apt-get install binutils-dev build-essential zlib1g-dev bison re2c flex + sudo apt-get install build-essential binutils-dev clang zlib1g-dev ``` - Windows - Download and install [Microsoft Visual Studio Community](https://visualstudio.microsoft.com/downloads/) for free. From a68a0b258795520b24aa51711736f30f03fe5b0e Mon Sep 17 00:00:00 2001 From: Saurabh Kumar <151380951+kmr-srbh@users.noreply.github.com> Date: Sat, 17 Feb 2024 12:12:31 +0530 Subject: [PATCH 5/7] Remove `flex` --- environment_unix.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/environment_unix.yml b/environment_unix.yml index ddea38dd0b..af7dffcff0 100644 --- a/environment_unix.yml +++ b/environment_unix.yml @@ -8,7 +8,6 @@ dependencies: - re2c - toml - zlib - - flex - cmake - numpy - flake8 From 94ea77078eed8d9e2ac98bf1585f02312a8c0311 Mon Sep 17 00:00:00 2001 From: Saurabh Kumar <151380951+kmr-srbh@users.noreply.github.com> Date: Sat, 17 Feb 2024 12:12:54 +0530 Subject: [PATCH 6/7] Remove `flex` --- environment_win.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/environment_win.yml b/environment_win.yml index 3da9d77cac..60774b822c 100644 --- a/environment_win.yml +++ b/environment_win.yml @@ -8,7 +8,6 @@ dependencies: - re2c - toml - zlib - - flex - cmake - ninja - numpy From de57a105cb5e0944236577cb55954de4b57e5ee0 Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Date: Tue, 27 Feb 2024 23:23:41 +0530 Subject: [PATCH 7/7] Improved `math.factorial()` function to work with very large values, with speed --- src/runtime/math.py | 191 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 162 insertions(+), 29 deletions(-) diff --git a/src/runtime/math.py b/src/runtime/math.py index 8655201892..c22d0e8540 100644 --- a/src/runtime/math.py +++ b/src/runtime/math.py @@ -15,36 +15,170 @@ def modf(x: f64) -> tuple[f64, f64]: """ return (x - f64(int(x)), float(int(x))) -@overload -def factorial(x: i32) -> i32: - """ - Computes the factorial of `x`. - """ - - result: i32 - result = 0 - if x < 0: - return result - result = 1 - i: i32 - for i in range(1, x+1): - result *= i - return result @overload -def factorial(x: i64) -> i64: - """ - Computes the factorial of `x`. - """ - result: i64 - result = i64(0) - if x < i64(0): - return result - result = i64(1) - i: i64 - for i in range(i64(1), x + i64(1)): - result *= i64(i) - return result +def factorial(n: i32) -> i64: + """Computes the factorial of `n`.""" + MAX_LOOKUP_VALUE: i32 = 20 + FACTORIAL_LOOKUP_TABLE: list[i64] = [ + i64(1), + i64(1), + i64(2), + i64(6), + i64(24), + i64(120), + i64(720), + i64(5040), + i64(40320), + i64(362880), + i64(3628800), + i64(39916800), + i64(479001600), + i64(6227020800), + i64(87178291200), + i64(1307674368000), + i64(20922789888000), + i64(355687428096000), + i64(6402373705728000), + i64(121645100408832000), + i64(2432902008176640000), + ] + if n < 0: + # Exceptions are not implemented currently + # raise ValueError("factorial() not defined for negative values") + assert 1 == 0, "factorial() not defined for negative values." + elif n < MAX_LOOKUP_VALUE: + return FACTORIAL_LOOKUP_TABLE[n] + else: + f: list[i32] = [0] * 4300 + f[0] = 0 + f[1] = 0 + f[2] = 0 + f[3] = 0 + f[4] = 4 + f[5] = 6 + f[6] = 6 + f[7] = 7 + f[8] = 1 + f[9] = 8 + f[10] = 0 + f[11] = 0 + f[12] = 2 + f[13] = 0 + f[14] = 9 + f[15] = 2 + f[16] = 3 + f[17] = 4 + f[18] = 2 + + f_size: i32 = 19 + + i: i32 = 21 + while i <= n: + index: i32 = 0 + carry: i32 = 0 + while index < f_size: + product: i32 = f[index] * i + carry + f[index] = product % 10 + + carry = product // 10 + index += 1 + + while carry > 0: + f[f_size] = carry % 10 + carry = carry // 10 + f_size += 1 + i += 1 + + result: str = "" + idx: i32 + for idx in range(f_size - 1, -1, -1): + result += str(f[idx]) + print(result) + return i64(0) + + +@overload +def factorial(n: i64) -> i64: + """Computes the factorial of `n`.""" + MAX_LOOKUP_VALUE: i64 = i64(20) + FACTORIAL_LOOKUP_TABLE: list[i64] = [ + i64(1), + i64(1), + i64(2), + i64(6), + i64(24), + i64(120), + i64(720), + i64(5040), + i64(40320), + i64(362880), + i64(3628800), + i64(39916800), + i64(479001600), + i64(6227020800), + i64(87178291200), + i64(1307674368000), + i64(20922789888000), + i64(355687428096000), + i64(6402373705728000), + i64(121645100408832000), + i64(2432902008176640000), + ] + if n < i64(0): + # Exceptions are not implemented currently + # raise ValueError("factorial() not defined for negative values") + assert 1 == 0, "factorial() not defined for negative values." + elif n < MAX_LOOKUP_VALUE: + return FACTORIAL_LOOKUP_TABLE[n] + else: + f: list[i32] = [0] * 4300 + f[0] = 0 + f[1] = 0 + f[2] = 0 + f[3] = 0 + f[4] = 4 + f[5] = 6 + f[6] = 6 + f[7] = 7 + f[8] = 1 + f[9] = 8 + f[10] = 0 + f[11] = 0 + f[12] = 2 + f[13] = 0 + f[14] = 9 + f[15] = 2 + f[16] = 3 + f[17] = 4 + f[18] = 2 + + f_size: i32 = 19 + + i: i32 = 21 + while i64(i) <= n: + index: i32 = 0 + carry: i32 = 0 + while index < f_size: + product: i32 = f[index] * i + carry + f[index] = product % 10 + + carry = product // 10 + index += 1 + + while carry > 0: + f[f_size] = carry % 10 + carry = carry // 10 + f_size += 1 + i += 1 + + result: str = "" + idx: i32 + for idx in range(f_size - 1, -1, -1): + result += str(f[idx]) + print(result) + return i64(0) + @overload def floor(x: i32) -> i32: @@ -457,7 +591,6 @@ def ldexp(x: f64, i: i32) -> f64: return result - def mod(a: i32, b: i32) -> i32: """ Returns a%b