diff --git a/.gitignore b/.gitignore index 54088d5..083546c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ target .DS_Store +.idea \ No newline at end of file diff --git a/src/main/java/edu/eci/arsw/math/Main.java b/src/main/java/edu/eci/arsw/math/Main.java index 605de12..a716088 100644 --- a/src/main/java/edu/eci/arsw/math/Main.java +++ b/src/main/java/edu/eci/arsw/math/Main.java @@ -5,7 +5,9 @@ */ package edu.eci.arsw.math; +import java.util.ArrayList; import java.util.Arrays; +import edu.eci.arsw.threads.PiThread; /** * @@ -14,9 +16,19 @@ public class Main { public static void main(String a[]) { - System.out.println(bytesToHex(PiDigits.getDigits(0, 10))); - System.out.println(bytesToHex(PiDigits.getDigits(1, 100))); - System.out.println(bytesToHex(PiDigits.getDigits(1, 1000000))); + int numThreads = 1; // Varia para cada experimento (1,8,16,200,500) + int numDigits = 1000000; + + System.out.println("Ejecutando con " + numThreads + " hilos..."); + + long startTime = System.nanoTime(); // Iniciar medición de tiempo + byte[] piDigits = PiDigits.getDigits(0, numDigits, numThreads); + long endTime = System.nanoTime(); // Finalizar medición de tiempo + + double elapsedTime = (endTime - startTime) / 1e9; // Convertir a segundos + System.out.println("Tiempo de ejecución: " + elapsedTime + " segundos"); + + System.out.println(bytesToHex(piDigits)); } private final static char[] hexArray = "0123456789ABCDEF".toCharArray(); @@ -35,5 +47,4 @@ public static String bytesToHex(byte[] bytes) { } return sb.toString(); } - -} +} \ No newline at end of file diff --git a/src/main/java/edu/eci/arsw/math/PiDigits.java b/src/main/java/edu/eci/arsw/math/PiDigits.java index 526cd7d..f780685 100644 --- a/src/main/java/edu/eci/arsw/math/PiDigits.java +++ b/src/main/java/edu/eci/arsw/math/PiDigits.java @@ -1,113 +1,65 @@ package edu.eci.arsw.math; -/// -/// An implementation of the Bailey-Borwein-Plouffe formula for calculating hexadecimal -/// digits of pi. -/// https://en.wikipedia.org/wiki/Bailey%E2%80%93Borwein%E2%80%93Plouffe_formula -/// *** Translated from C# code: https://github.com/mmoroney/DigitsOfPi *** -/// -public class PiDigits { - - private static int DigitsPerSum = 8; - private static double Epsilon = 1e-17; +import java.util.ArrayList; +import edu.eci.arsw.threads.PiThread; +public class PiDigits { - /** - * Returns a range of hexadecimal digits of pi. - * @param start The starting location of the range. - * @param count The number of digits to return - * @return An array containing the hexadecimal digits. - */ - public static byte[] getDigits(int start, int count) { - if (start < 0) { - throw new RuntimeException("Invalid Interval"); + private static ArrayList threads = new ArrayList<>(); + private static byte[] digits; + + public static byte[] getDigits(int start, int count, int threadNumber) { + + digits = new byte[count]; + threads.clear(); + + if (threadNumber > count) { + threadNumber = count; } - if (count < 0) { - throw new RuntimeException("Invalid Interval"); - } + int digitsPerThread = count / threadNumber; + int remainingDigits = count % threadNumber; + int currentStart = start; - byte[] digits = new byte[count]; - double sum = 0; + System.out.println("Iniciando cálculo con " + threadNumber + " hilos..."); - for (int i = 0; i < count; i++) { - if (i % DigitsPerSum == 0) { - sum = 4 * sum(1, start) - - 2 * sum(4, start) - - sum(5, start) - - sum(6, start); + long startTime = System.nanoTime(); // Medir tiempo de inicio - start += DigitsPerSum; + for (int i = 0; i < threadNumber; i++) { + int digitsForThisThread = digitsPerThread; + if (i == threadNumber - 1) { + digitsForThisThread += remainingDigits; } - sum = 16 * (sum - Math.floor(sum)); - digits[i] = (byte) sum; + int threadEnd = currentStart + digitsForThisThread; + + PiThread thread = new PiThread(currentStart, threadEnd); + threads.add(thread); + thread.start(); + + currentStart = threadEnd; } - return digits; - } - - /// - /// Returns the sum of 16^(n - k)/(8 * k + m) from 0 to k. - /// - /// - /// - /// - private static double sum(int m, int n) { - double sum = 0; - int d = m; - int power = n; - - while (true) { - double term; - - if (power > 0) { - term = (double) hexExponentModulo(power, d) / d; - } else { - term = Math.pow(16, power) / d; - if (term < Epsilon) { - break; - } + try { + for (PiThread thread : threads) { + thread.join(); } - - sum += term; - power--; - d += 8; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException("Calculation interrupted", e); } - return sum; - } - - /// - /// Return 16^p mod m. - /// - /// - /// - /// - private static int hexExponentModulo(int p, int m) { - int power = 1; - while (power * 2 <= p) { - power *= 2; - } - - int result = 1; - - while (power > 0) { - if (p >= power) { - result *= 16; - result %= m; - p -= power; - } - - power /= 2; + long endTime = System.nanoTime(); // Medir tiempo de finalización + double elapsedTime = (endTime - startTime) / 1e9; + System.out.println("Tiempo total de ejecución en PiDigits: " + elapsedTime + " segundos"); - if (power > 0) { - result *= result; - result %= m; - } + int offset = 0; + for (PiThread thread : threads) { + byte[] threadDigits = thread.getDigits(); + System.arraycopy(threadDigits, 0, digits, offset, threadDigits.length); + offset += threadDigits.length; } - return result; + return digits; } - -} +} \ No newline at end of file diff --git a/src/main/java/edu/eci/arsw/threads/CountThread.java b/src/main/java/edu/eci/arsw/threads/CountThread.java index dc5f7d0..0b59d73 100644 --- a/src/main/java/edu/eci/arsw/threads/CountThread.java +++ b/src/main/java/edu/eci/arsw/threads/CountThread.java @@ -4,11 +4,38 @@ * and open the template in the editor. */ package edu.eci.arsw.threads; +import java.lang.Thread; + /** * - * @author hcadavid + * @author Team 2 (Samuel, Juan, Valentina) */ -public class CountThread { - -} +public class CountThread extends Thread { + + private int A; + private int B; + + public CountThread(int A, int B){ + this.A = A; + this.B = B; + } + + public void run(){ + printed(); + } + + public int getA(){ + return A; + } + + public int getB(){ + return B; + } + + public void printed(){ + for (int i = getA(); i<= getB();i++ ){ + System.out.println(i); + } + } +} \ No newline at end of file diff --git a/src/main/java/edu/eci/arsw/threads/CountThreadsMain.java b/src/main/java/edu/eci/arsw/threads/CountThreadsMain.java index 482f513..500e251 100644 --- a/src/main/java/edu/eci/arsw/threads/CountThreadsMain.java +++ b/src/main/java/edu/eci/arsw/threads/CountThreadsMain.java @@ -7,12 +7,18 @@ /** * - * @author hcadavid + * @author Team 2 (Samuel, Juan, Valentina) */ public class CountThreadsMain { public static void main(String a[]){ + CountThread countThread1 = new CountThread(0, 99); + CountThread countThread2 = new CountThread(99, 199); + CountThread countThread3= new CountThread(199, 299); + countThread1.run(); + countThread2.run(); + countThread3.run(); } } diff --git a/src/main/java/edu/eci/arsw/threads/PiThread.java b/src/main/java/edu/eci/arsw/threads/PiThread.java new file mode 100644 index 0000000..321723d --- /dev/null +++ b/src/main/java/edu/eci/arsw/threads/PiThread.java @@ -0,0 +1,101 @@ +package edu.eci.arsw.threads; + +public class PiThread extends Thread { + + private static int DigitsPerSum = 8; + private static double Epsilon = 1e-17; + + private byte[] digits; + private int start; + private int count; + + public PiThread(int start, int end) { + this.start = start; + this.count = end - start; + this.digits = new byte[this.count]; + } + + public void run() { + piDigits(); + } + + public byte[] piDigits() { + if (start < 0 || count < 0) { + throw new RuntimeException("Invalid Interval"); + } + + double sum = 0; + int currentPosition = start; + + for (int i = 0; i < count; i++) { + if (i % DigitsPerSum == 0) { + sum = 4 * sum(1, currentPosition) + - 2 * sum(4, currentPosition) + - sum(5, currentPosition) + - sum(6, currentPosition); + + currentPosition += DigitsPerSum; + } + + sum = 16 * (sum - Math.floor(sum)); + digits[i] = (byte) Math.floor(sum); + } + + return digits; + } + + public byte[] getDigits() { + return digits; + } + + private static double sum(int m, int n) { + double sum = 0; + int d = m; + int power = n; + + while (true) { + double term; + + if (power > 0) { + term = (double) hexExponentModulo(power, d) / d; + } else { + term = Math.pow(16, power) / d; + if (term < Epsilon) { + break; + } + } + + sum += term; + power--; + d += 8; + } + + return sum; + } + + private static int hexExponentModulo(int p, int m) { + int power = 1; + while (power * 2 <= p) { + power *= 2; + } + + int result = 1; + + while (power > 0) { + if (p >= power) { + result *= 16; + result %= m; + p -= power; + } + + power /= 2; + + if (power > 0) { + result *= result; + result %= m; + } + } + + return result; + } +} \ No newline at end of file diff --git a/src/test/java/edu/eci/arsw/math/PiCalcTest.java b/src/test/java/edu/eci/arsw/math/PiCalcTest.java index 38d7569..e953aea 100644 --- a/src/test/java/edu/eci/arsw/math/PiCalcTest.java +++ b/src/test/java/edu/eci/arsw/math/PiCalcTest.java @@ -38,8 +38,89 @@ public void piGenTest() throws Exception { 0x3, 0x8, 0xD, 0x0, 0x1, 0x3, 0x7, 0x7,}; for (int start = 0; start < expected.length; start++) { - for (int count = 0; count < expected.length - start; count++) { - byte[] digits = PiDigits.getDigits(start, count); + for (int count = 1; count <= expected.length - start; count++) { + byte[] digits = PiDigits.getDigits(start, count,3); + assertEquals(count, digits.length); + + for (int i = 0; i < digits.length; i++) { + assertEquals(expected[start + i], digits[i]); + } + } + } + } + + @Test + public void piGenTestWith1Thread() throws Exception { + + byte[] expected = new byte[]{ + 0x2, 0x4, 0x3, 0xF, 0x6, 0xA, 0x8, 0x8, + 0x8, 0x5, 0xA, 0x3, 0x0, 0x8, 0xD, 0x3, + 0x1, 0x3, 0x1, 0x9, 0x8, 0xA, 0x2, 0xE, + 0x0, 0x3, 0x7, 0x0, 0x7, 0x3, 0x4, 0x4, + 0xA, 0x4, 0x0, 0x9, 0x3, 0x8, 0x2, 0x2, + 0x2, 0x9, 0x9, 0xF, 0x3, 0x1, 0xD, 0x0, + 0x0, 0x8, 0x2, 0xE, 0xF, 0xA, 0x9, 0x8, + 0xE, 0xC, 0x4, 0xE, 0x6, 0xC, 0x8, 0x9, + 0x4, 0x5, 0x2, 0x8, 0x2, 0x1, 0xE, 0x6, + 0x3, 0x8, 0xD, 0x0, 0x1, 0x3, 0x7, 0x7,}; + + for (int start = 0; start < expected.length; start++) { + for (int count = 1; count <= expected.length - start; count++) { + byte[] digits = PiDigits.getDigits(start, count,1); + assertEquals(count, digits.length); + + for (int i = 0; i < digits.length; i++) { + assertEquals(expected[start + i], digits[i]); + } + } + } + } + + @Test + public void piGenTestWith2Thread() throws Exception { + + byte[] expected = new byte[]{ + 0x2, 0x4, 0x3, 0xF, 0x6, 0xA, 0x8, 0x8, + 0x8, 0x5, 0xA, 0x3, 0x0, 0x8, 0xD, 0x3, + 0x1, 0x3, 0x1, 0x9, 0x8, 0xA, 0x2, 0xE, + 0x0, 0x3, 0x7, 0x0, 0x7, 0x3, 0x4, 0x4, + 0xA, 0x4, 0x0, 0x9, 0x3, 0x8, 0x2, 0x2, + 0x2, 0x9, 0x9, 0xF, 0x3, 0x1, 0xD, 0x0, + 0x0, 0x8, 0x2, 0xE, 0xF, 0xA, 0x9, 0x8, + 0xE, 0xC, 0x4, 0xE, 0x6, 0xC, 0x8, 0x9, + 0x4, 0x5, 0x2, 0x8, 0x2, 0x1, 0xE, 0x6, + 0x3, 0x8, 0xD, 0x0, 0x1, 0x3, 0x7, 0x7,}; + + for (int start = 0; start < expected.length; start++) { + for (int count = 1; count <= expected.length - start; count++) { + byte[] digits = PiDigits.getDigits(start, count,2); + assertEquals(count, digits.length); + + for (int i = 0; i < digits.length; i++) { + assertEquals(expected[start + i], digits[i]); + } + } + } + } + + @Test + public void piGenTestWith3Thread() throws Exception { + + byte[] expected = new byte[]{ + 0x2, 0x4, 0x3, 0xF, 0x6, 0xA, 0x8, 0x8, + 0x8, 0x5, 0xA, 0x3, 0x0, 0x8, 0xD, 0x3, + 0x1, 0x3, 0x1, 0x9, 0x8, 0xA, 0x2, 0xE, + 0x0, 0x3, 0x7, 0x0, 0x7, 0x3, 0x4, 0x4, + 0xA, 0x4, 0x0, 0x9, 0x3, 0x8, 0x2, 0x2, + 0x2, 0x9, 0x9, 0xF, 0x3, 0x1, 0xD, 0x0, + 0x0, 0x8, 0x2, 0xE, 0xF, 0xA, 0x9, 0x8, + 0xE, 0xC, 0x4, 0xE, 0x6, 0xC, 0x8, 0x9, + 0x4, 0x5, 0x2, 0x8, 0x2, 0x1, 0xE, 0x6, + 0x3, 0x8, 0xD, 0x0, 0x1, 0x3, 0x7, 0x7,}; + + for (int start = 0; start < expected.length; start++) { + for (int count = 1; count <= expected.length - start; count++) { + byte[] digits = PiDigits.getDigits(start, count,3); assertEquals(count, digits.length); for (int i = 0; i < digits.length; i++) {