I have implemented a solutions for multiplying any two large numbers, the solution I am getting seems to be working fine for many inputs however when I pass
"3141592653589793238462643383279502884197169399375105820974944592"
"2718281828459045235360287471352662497757247093699959574966967627"
It's not giving correct answer
I am using Basic Java Syntax
import java.util.*;
public class GenericOperations {
static String addTwoLargeNumber(String X, String Y)
{
String Z = "";
int i = X.length() - 1;
int j = Y.length() - 1;
int carry = 0;
while(i>-1 && j>-1)
{
int digitSum = Character.getNumericValue(X.charAt(i)) +
Character.getNumericValue(Y.charAt(j)) + carry;
if(digitSum > 9)
{
Z = digitSum%10 + Z;
carry=1;
}
else
{
Z = digitSum + Z;
carry = 0;
}
i--;j--;
}
while(i>-1)
{
int digitSum = Character.getNumericValue(X.charAt(i)) + carry;
if(digitSum > 9)
{
Z = digitSum%10 + Z;
carry=1;
}
else
{
Z = digitSum + Z;
carry = 0;
}
i--;
}
while(j>-1)
{
int digitSum = Character.getNumericValue(Y.charAt(j)) + carry;
if(digitSum > 9)
{
Z = digitSum%10 + Z;
carry=1;
}
else
{
Z = digitSum + Z ;
carry = 0;
}
j--;
}
return Z;
}
static String multiplyTwoLargeNumbers(String X, String Y)
{
ArrayList<String> additionList = new ArrayList<String>();
ArrayList<String> additionListWithZeros = new ArrayList<String>();
int n = X.length() - 1;
int m = Y.length() - 1 ;
int carry = 0;
int i=0,j=0;
for(i=n ; i>-1; i--)
{
carry = 0;
String Z = "";
for(j = m ; j>-1 ; j--)
{
int digitSum = ( Character.getNumericValue(X.charAt(i)) *
Character.getNumericValue(Y.charAt(j)) )
+ carry;
if(digitSum > 9)
{
Z = digitSum%10 + Z;
carry= digitSum/10;
}
else
{
Z = digitSum + Z;
carry = 0;
}
}
if(carry!=0)
{
Z = carry + Z;
}
additionList.add(Z);
}
int k = 0;
String sum = "";
for (Iterator<String> iterator = additionList.iterator(); iterator.hasNext();)
{
String val1 = iterator.next();
for(int x = 0;x<k;x++)
{
val1 = val1 + 0;
}
k++;
//System.out.println(val1);
sum = addTwoLargeNumber(sum,val1);
}
return sum;
}
static void printArray(int arr[])
{
int n = arr.length;
for (int i=0; i<n; ++i)
{
System.out.print(arr[i] + " ");
}
System.out.println();
}
public static void main(String args[])
{
String val = multiplyTwoLargeNumbers(
"3141592653589793238462643383279502884197169399375105820974944592",
"2718281828459045235360287471352662497757247093699959574966967627");
System.out.println(val);
}
}
Expected Result:
8539734222673567065463550869546574495034888535765114961879601127067743044893204848617875072216249073013374895871952806582723184
Actual Results:
8539734222673566965463549869546574495034887534765114961879601127067743044893204848617875072216249073013374895871952806582723184
You just missed a carry when adding.
Add following and you should be done:
if (carry != 0) {
Z = carry + Z;
}
BTW: simplified the addTwoLargeNumber-method
static String addTwoLargeNumber(String X, String Y) {
String Z = "";
int maxPos = Math.max(X.length(), Y.length());
int carry = 0;
for (int pos = 0; pos < maxPos; pos++) {
final int currValX
= pos < X.length()
? Character.getNumericValue(X.charAt(X.length() - 1 - pos)) : 0;
final int currValY
= pos < Y.length()
? Character.getNumericValue(Y.charAt(Y.length() - 1 - pos)) : 0;
int digitSum = currValX + currValY + carry;
Z = digitSum % 10 + Z;
carry = digitSum / 10;
}
if (carry != 0) {
Z = carry + Z;
}
return Z;
}
Made a new sketch on openprocessing.org to test for some different grade combinations quickly... but whenever I run it, the page freezes hangs until chrome says that it is unresponsive. My other sketches are working just fine, it is only this one.
Here is the sketch:
double a, o, u, k;
int[][] combos;
int[][] a_combos, b_combos;
int failcounter;
void setup() {
size(100,100);
background(100);
noLoop();
a = 2 + 4;
o = 4 + 4;
u = 3 + 4;
k = 3 + 5;
combos = new int[10000][4];
a_combos = new int[10000][4];
b_combos = new int[10000][4];
failcounter = 0;
}
void draw() {
fillCombos();
for (int i = 0; i < combos.length; i++) {
double atemp = a + combos[0];
double otemp = o + combos[1];
double utemp = u + combos[2];
double ktemp = k + combos[3];
double avg = (atemp + otemp + utemp + ktemp) / 4;
if (avg >= 17) {
a_combos[i] = combos[i];
} else if (avg >= 13.48) {
b_combos[i] = combos[i];
} else {
failcounter++;
}
}
println("Getting an A:");
for (int i = 0; i < a_combos.length; i++) {
if (a_combos[i] != null) println(a_combos[i]);
}
println("Getting a B:");
for (int i = 0; i < b_combos.length; i++) {
if (b_combos[i] != null) println(b_combos[i]);
}
println("A or B versus C, D, or F:");
println(10000 - failcount + ", " + failcount);
}
void fillCombos() {
int q = 0;
int w = 0;
int e = 0;
int r = 0;
for (int i = 0; i < combos.length; i++) {
combos[i][0] = q;
combos[i][1] = w;
combos[i][2] = e;
combos[i][3] = r;
r++;
if (r == 10) {
r = 0;
e++;
}
if (e == 10) {
e = 0;
w++;
}
if (w == 10) {
w = 0;
q++;
}
}
}
If I put print lines into several different locations in the code, none of them run for whatever reason. Any insight?
I am learning JCuda and studying with JCuda samples.
When I studied a KMeans algorithm code using JCuda, I got a "CUDA_ERROR_ILLEGAL_ADDRESS" when executed line cuCtxSynchronize();
It confused me a lot. How can I solve it?
Here is KMeansKernel.cu
extern "C"
__global__ void add(int n, float *a, float *b, float *sum)
{
int i = blockIdx.x * blockDim.x + threadIdx.x;
if (i<n)
{
sum[i] = a[i] + b[i];
}
}
Main method(my class named "CUDA"):
public static void main(String[] args){
// omit some code which input kinds of parameters
try {
// Open image file
BufferedImage bi = ImageIO.read(picFiles);
if (bi == null) {
System.out.println("ERROR: File input error.");
return;
}
// Read image data
int length = bi.getWidth() * bi.getHeight();
int[] imageProperty = new int[length*5];
int[] pixel;
int count = 0;
for (int y = 0; y < bi.getHeight(); y++) {
for (int x = 0; x < bi.getWidth(); x++) {
pixel = bi.getRaster().getPixel(x, y, new int[4]);
imageProperty[count*5 ] = pixel[0];
imageProperty[count*5+1] = pixel[1];
imageProperty[count*5+2] = pixel[2];
imageProperty[count*5+3] = x;
imageProperty[count*5+4] = y;
count++;
}
}
//setup
JCudaDriver.setExceptionsEnabled(true);
// Create the PTX file
String ptxFileName;
try
{
ptxFileName = preparePtxFile("KmeansKernel.cu");
}
catch (IOException e)
{
System.out.println("Warning...");
System.out.println(e.getMessage());
System.out.println("Exiting...");
return;
}
cuInit(0);
CUdevice device = new CUdevice();
cuDeviceGet(device, 0);
CUcontext context = new CUcontext();
cuCtxCreate(context, 0, device);
CUmodule module = new CUmodule();
cuModuleLoad(module, ptxFileName);
CUfunction kmeansFunction = new CUfunction();
System.out.println("x");
cuModuleGetFunction(kmeansFunction, module, "add");
//copy host input to device
CUdeviceptr imageDevice = new CUdeviceptr();
cuMemAlloc(imageDevice, imageProperty.length * Sizeof.INT);
cuMemcpyHtoD(imageDevice, Pointer.to(imageProperty), imageProperty.length * Sizeof.INT);
int blockSizeX = 256;
int gridSizeX = (int) Math.ceil((double)(imageProperty.length / 5) / blockSizeX);
long et = System.currentTimeMillis();
System.out.println(((double)(et-st)/1000.0) + "s");
for (int k = startClusters; k <= endClusters; k++) {
long startTime = System.currentTimeMillis();
int[] clusters = new int[length];
int[] c = new int[k*5];
int h = 0;
for(int i = 0; i < k; i++) {
c[i*5] = imageProperty[h*5];
c[i*5+1] = imageProperty[h*5+1];
c[i*5+2] = imageProperty[h*5+2];
c[i*5+3] = imageProperty[h*5+3];
c[i*5+4] = imageProperty[h*5+4];
h += length / k;
}
double tolerance = 1e-4;
**//got warning in following line
CUDA.KmeansKernel(kmeansFunction, imageDevice, imageProperty, clusters, c, k, tolerance, distanceWeight, colorWeight, blockSizeX, gridSizeX);**
int[] output = calculateAveragePixels(imageProperty, clusters);
BufferedImage outputImage = new BufferedImage(bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_INT_RGB);
for (int i = 0; i < length; i++) {
int rgb = output[i*5];
rgb = (rgb * 256) + output[i*5+1];
rgb = (rgb * 256) + output[i*5+2];
outputImage.setRGB(i%bi.getWidth(), i/bi.getWidth(), rgb);
}
String fileName = (picFiles.getName()) + ".bmp";
File outputFile = new File("output/" + fileName);
ImageIO.write(outputImage, "BMP", outputFile);
long runTime = System.currentTimeMillis() - startTime;
System.out.println("Completed iteration k=" + k + " in " + ((double)runTime/1000.0) + "s");
}
System.out.println("Files saved to " + outputDirectory.getAbsolutePath() + "\\");
cuMemFree(imageDevice);
} catch (IOException e) {
e.printStackTrace();
}
}
Method KmeansKernel:
private static void KmeansKernel(CUfunction kmeansFunction, CUdeviceptr imageDevice, int[] imageProperty, int[] clusters, int[] c,
int k, double tolerance, double distanceWeight, double colorWeight,
int blockSizeX, int gridSizeX) {
CUdeviceptr clustersDevice = new CUdeviceptr();
cuMemAlloc(clustersDevice, clusters.length * Sizeof.INT);
// Alloc device output
CUdeviceptr centroidPixels = new CUdeviceptr();
cuMemAlloc(centroidPixels, k * 5 * Sizeof.INT);
CUdeviceptr errorDevice = new CUdeviceptr();
cuMemAlloc(errorDevice, Sizeof.DOUBLE * clusters.length);
int[] c1 = new int[k*5];
cuMemcpyHtoD(centroidPixels, Pointer.to(c), Sizeof.INT * 5 * k);
// begin algorithm
int[] counts = new int[k];
double old_error, error = Double.MAX_VALUE;
int l = 0;
do {
l++;
old_error = error;
error = 0;
Arrays.fill(counts, 0);
Arrays.fill(c1, 0);
cuMemcpyHtoD(centroidPixels, Pointer.to(c), k * 5 * Sizeof.INT);
Pointer kernelParameters = Pointer.to(
Pointer.to(new int[] {clusters.length}),
Pointer.to(new int[] {k}),
Pointer.to(new double[] {colorWeight}),
Pointer.to(new double[] {distanceWeight}),
Pointer.to(errorDevice),
Pointer.to(imageDevice),
Pointer.to(centroidPixels),
Pointer.to(clustersDevice)
);
cuLaunchKernel(kmeansFunction,
gridSizeX, 1, 1,
blockSizeX, 1, 1,
0, null,
kernelParameters, null
);
**cuCtxSynchronize(); //got warning here.why?**
cuMemcpyDtoH(Pointer.to(clusters), clustersDevice, Sizeof.INT*clusters.length);
for (int i = 0; i < clusters.length; i++) {
int cluster = clusters[i];
counts[cluster]++;
c1[cluster*5] += imageProperty[i*5];
c1[cluster*5+1] += imageProperty[i*5+1];
c1[cluster*5+2] += imageProperty[i*5+2];
c1[cluster*5+3] += imageProperty[i*5+3];
c1[cluster*5+4] += imageProperty[i*5+4];
}
for (int i = 0; i < k; i++) {
if (counts[i] > 0) {
c[i*5] = c1[i*5] / counts[i];
c[i*5+1] = c1[i*5+1] / counts[i];
c[i*5+2] = c1[i*5+2] / counts[i];
c[i*5+3] = c1[i*5+3] / counts[i];
c[i*5+4] = c1[i*5+4] / counts[i];
} else {
c[i*5] = c1[i*5];
c[i*5+1] = c1[i*5+1];
c[i*5+2] = c1[i*5+2];
c[i*5+3] = c1[i*5+3];
c[i*5+4] = c1[i*5+4];
}
}
double[] errors = new double[clusters.length];
cuMemcpyDtoH(Pointer.to(errors), errorDevice, Sizeof.DOUBLE*clusters.length);
error = sumArray(errors);
System.out.println("" + l + " iterations");
} while (Math.abs(old_error - error) > tolerance);
cuMemcpyDtoH(Pointer.to(clusters), clustersDevice, clusters.length * Sizeof.INT);
cuMemFree(errorDevice);
cuMemFree(centroidPixels);
cuMemFree(clustersDevice);
}
Stack trace:
Exception in thread "main" jcuda.CudaException: CUDA_ERROR_ILLEGAL_ADDRESS
at jcuda.driver.JCudaDriver.checkResult(JCudaDriver.java:330)
at jcuda.driver.JCudaDriver.cuCtxSynchronize(JCudaDriver.java:1938)
at com.test.CUDA.KmeansKernel(CUDA.java:269)
at com.test.CUDA.main(CUDA.java:184)
As #talonmies mentions, the kernelParameters you are passing to the cuLaunchKernel method are not in line with add kernel function signature.
You get the error at cuCtxSynchronize because CUDA execution model is asynchronous: cuLaunchKernel returns immediately and actual execution of the kernel on the device is asynchronous. cuCtxSynchronize documentation reads:
Note that this function may also return error codes from previous, asynchronous launches.
The second kernelParameters entry is an int k, where the second parameter of add method is a pointer to float, hence most probably the illegal access error.
I am making a project in which I need to put a certain precision(0.00 or 0.000) on values in a 2d array. The 2d array is a String and i want to convert it to double. But when I try, I get a NullPointerException, I don't know why.
Afterwards I want to again convert it to a String array.
print-method code:
public void printSheet() {
int start = 'a';
char letter = (char) start;
//kolomnamen
for (int i = 0; i < COLUMNS + 1; i++) {
if (i == 0) {
System.out.print(" ");
} else if (WIDTH != 0) {
String s = "";
for (int j = 0; j < WIDTH / 2; j++) {
s += "-";
}
s += (char) (letter + i - 1);
for (int j = 0; j < WIDTH / 2; j++) {
s += "-";
}
System.out.print(s + "\t");
}
}
System.out.println("\n");
for (int i = 0; i < sheet.length; i++) {
System.out.print(1 + i + "." + " ");
for (int j = 0; j < sheet[i].length; j++) {
double[][] voorlopig = null;
voorlopig[i][j] = Double.parseDouble(sheet[i][j]); //<-- problem
double d = voorlopig[i][j];
// String s = " " + sheet[i][j];
System.out.println(voorlopig);
double thaprez = (precision / precision) + (Math.pow(precision, 10)) - 1;
d = Math.floor(d * thaprez + .5) / thaprez;
String s = " " + voorlopig[i][j];
if (sheet[i][j] == null) {
System.out.print(s + "\t\t");
} else if (sheet[i][j].length() < 10) {
System.out.print(s + "\t");
} else {
System.out.print(s);
}
}
System.out.println("\n");
}
}
Thanks in advance.
Try to initialize your array double[][] voorlopig maybe like this:
double[][] voorlopig = new double[sheet.length][sheet.length];
You get NullPointerException because the array voorlopig was double[][] voorlopig = null;
double[][] voorlopig = null;
voorlopig[i][j] = Double.parseDouble(sheet[i][j]);
voorlopig is set to null, you'll get a NullPointerException.Initialize voorlopig before using it.
I am trying to implement the rectangular/lattice multiplication in Java. For those who don't know, this is a short tutorial.
I tried some methods wherein I used a single array to store multiplication of two digits and sigma-append zeroes to it. Once all the numbers are multiplied, I pick two elements from the array and then add the sigma value and fetch two more numbers and again perform the same thing until all the numbers are fetched.
The logic works fine but I am not able to find the exact number of zeroes that I should maintain, since for every different set of numbers (4 digits * 3 digits) I get different number of zeroes.
Could somebody please help?
I liked the tutorial, very neat. So I wanted to implement it, but not do your project work. So I came up with a lousy, quick and dirty implementation, violating many of the design rules I practice myself. I used arrays to save the digit by digit multiplication results, and pretty much followed what the tutorial said. I never have had to count the number of 0's, and I am not sure what is sigma-appending, so I cannot answer that. Lastly, there is a bug in the code which shows up when the 2 numbers have a different count of digits. Here is the source code - feel free to edit and use any part. I think an easy fix would be to prepend 0's to the smaller number to make the digit count the same for the 2 numbers, and not to display the corresponding row/columns. More bookkeeping, but thats up to you.
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Lattice extends JPanel implements ActionListener {
protected Font axisFont, rectFont, carrFont;
protected Color boxColor = new Color (25, 143, 103), gridColor = new Color (78, 23, 211),
diagColor = new Color (93, 192, 85), fontColor = new Color (23, 187, 98),
carrColor = new Color (162, 34, 19);
protected int nDigitP, nDigitQ, dSize = 60,
m1, m2, lastCarry, iResult[],
xDigits[], yDigits[], prodTL[][], prodBR[][];
public Lattice (int p, int q, Font font) {
nDigitP = (int) Math.ceil (Math.log10 (p)); xDigits = new int[nDigitP];
nDigitQ = (int) Math.ceil (Math.log10 (q)); yDigits = new int[nDigitQ];
prodTL = new int[nDigitP][nDigitQ]; prodBR = new int[nDigitP][nDigitQ];
m1 = p; m2 = q; // To display in report
int np = p, nq = q, size = font.getSize(); // Save the digits in array
for (int i = 0 ; i < nDigitP ; i++) {
xDigits[i] = np % 10;
np /= 10;
}
for (int i = 0 ; i < nDigitQ ; i++) {
yDigits[i] = nq % 10;
nq /= 10;
}
for (int i = 0 ; i < nDigitP ; i++) { // Cell products as upper/lower matrix
for (int j = 0 ; j < nDigitQ ; j++) {
int prod = xDigits[i] * yDigits[j];
prodTL[i][j] = prod / 10;
prodBR[i][j] = prod % 10;
}}
axisFont = font.deriveFont (Font.PLAIN, size+8.0f);
rectFont = font.deriveFont (Font.PLAIN, size+4.0f);
carrFont = font.deriveFont (Font.PLAIN);
setPreferredSize (new Dimension ((nDigitP+2)*dSize, (nDigitQ+2)*dSize));
}
public void paint (Graphics g) {
int w = getWidth(), h = getHeight();
Graphics2D g2 = (Graphics2D) g; // To make diagonal lines smooth
g2.setPaint (Color.white);
g2.fillRect (0,0,w,h);
int dx = (int) Math.round (w/(2.0+nDigitP)), // Grid spacing to position
dy = (int) Math.round (h/(2.0+nDigitQ)); // the lines and the digits
g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint (RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.setFont (axisFont);
FontMetrics fm = g2.getFontMetrics();
for (int i = 0 ; i < nDigitP ; i++) { // Grid || Y-axis and labels on axis
int px = w - (i+1)*dx;
g2.setPaint (gridColor);
if (i > 0)
g2.drawLine (px, dy, px, h-dy);
String str = /*i + */"" + xDigits[i];
int strw = fm.stringWidth (str);
g2.setPaint (fontColor);
g2.drawString (str, px-dx/2-strw/2, 4*dy/5);
}
for (int i = 0 ; i < nDigitQ ; i++) { // Grid || X-axis and labels on axis
int py = h - (i+1)*dy;
g2.setPaint (gridColor);
if (i > 0)
g2.drawLine (dx, py, w-dx, py);
String str = /*i + */"" + yDigits[i];
int strw = fm.stringWidth (str);
g2.setPaint (fontColor);
g2.drawString (str, w-dx+2*dx/5-strw/2, py-dy/2+10);
}
g2.setFont (rectFont);
fm = g2.getFontMetrics(); // Upper/Lower traingular product matrix
for (int i = 0 ; i < nDigitP ; i++) {
for (int j = 0 ; j < nDigitQ ; j++) {
int px = w - (i+1)*dx;
int py = h - (j+1)*dy;
String strT = "" + prodTL[i][j];
int strw = fm.stringWidth (strT);
g2.drawString (strT, px-3*dx/4-strw/2, py-3*dy/4+5);
String strB = "" + prodBR[i][j];
strw = fm.stringWidth (strB);
g2.drawString (strB, px-dx/4-strw/2, py-dy/4+5);
}}
g2.setFont (axisFont);
fm = g2.getFontMetrics();
int carry = 0;
Vector cVector = new Vector(), iVector = new Vector();
for (int k = 0 ; k < 2*Math.max (nDigitP, nDigitQ) ; k++) {
int dSum = carry, i = k/2, j = k/2;
//System.out.println ("k="+k);
if ((k % 2) == 0) { // even k
if (k/2 < nDigitP && k/2 < nDigitQ)
dSum += prodBR[k/2][k/2];
// go right and top
for (int c = 0 ; c < k ; c++) {
if (--i < 0)
break;
if (i < nDigitP && j < nDigitQ)
dSum += prodTL[i][j];
//System.out.println (" >> TL (i,j) = (" + i+","+j+")");
if (++j == nDigitQ)
break;
if (i < nDigitP && j < nDigitQ)
dSum += prodBR[i][j];
//System.out.println (" >> BR (i,j) = (" + i+","+j+")");
}
// go bottom and left
i = k/2; j = k/2;
for (int c = 0 ; c < k ; c++) {
if (--j < 0)
break;
if (i < nDigitP && j < nDigitQ)
dSum += prodTL[i][j];
//System.out.println (" >> TL (i,j) = (" + i+","+j+")");
if (++i == nDigitP)
break;
if (i < nDigitP && j < nDigitQ)
dSum += prodBR[i][j];
//System.out.println (" >> BR (i,j) = (" + i+","+j+")");
}} else { // odd k
if (k/2 < nDigitP && k/2 < nDigitQ)
dSum += prodTL[k/2][k/2];
// go top and right
for (int c = 0 ; c < k ; c++) {
if (++j == nDigitQ)
break;
if (i < nDigitP && j < nDigitQ)
dSum += prodBR[i][j];
//System.out.println (" >> BR (i,j) = (" + i+","+j+")");
if (--i < 0)
break;
if (i < nDigitP && j < nDigitQ)
dSum += prodTL[i][j];
//System.out.println (" >> TL (i,j) = (" + i+","+j+")");
}
i = k/2; j = k/2;
// go left and bottom
for (int c = 0 ; c < k ; c++) {
if (++i == nDigitP)
break;
if (i < nDigitP && j < nDigitQ)
dSum += prodBR[i][j];
//System.out.println (" >> BR (i,j) = (" + i+","+j+")");
if (--j < 0)
break;
if (i < nDigitP && j < nDigitQ)
dSum += prodTL[i][j];
//System.out.println (" >> TL (i,j) = (" + i+","+j+")");
}}
int digit = dSum % 10; carry = dSum / 10;
cVector.addElement (new Integer (carry));
iVector.addElement (new Integer (digit));
String strD = "" + digit;
int strw = fm.stringWidth (strD);
if (k < nDigitP) {
int px = w - (k+1)*dx - 4*dx/5, py = h-dy + fm.getHeight();
g2.drawString (strD, px-strw/2, py);
} else {
int px = dx - 12, py = h - (k-nDigitP+1)*dy - dy/4;
g2.drawString (strD, px-strw/2, py+5);
}} // End k-loop
g2.setPaint (diagColor);
for (int i = 0 ; i < nDigitP ; i++) {
int xt = (i+1) * dx,
yb = (i+2) * dy;
g2.drawLine (xt, dy, 0, yb);
}
for (int i = 0 ; i < nDigitQ ; i++) {
int xb = (i + nDigitP - nDigitQ) * dx,
yr = (i+1) * dy;
g2.drawLine (w-dx, yr, xb, h);
}
// System.out.println ("carry Vector has " + cVector.size() + " elements");
g2.setFont (carrFont);
g2.setPaint (carrColor);
fm = g2.getFontMetrics();
for (int k = 0 ; k < 2*Math.max (nDigitP, nDigitQ) ; k++) {
carry = ((Integer) cVector.elementAt (k)).intValue();
lastCarry = carry; // To display
if (carry == 0)
continue;
String strC = "" + carry;
int strw = fm.stringWidth (strC),
px = w-dx-5-strw/2, // Const X while going Up
py = dy + fm.getHeight(); // Const Y while going Left
if (k < (nDigitQ-1))
py = h-(k+3)*dy + dy/5 + fm.getHeight();
else
px = w - (k-nDigitQ+2) * dx - dx/2 - strw/2;
g2.drawString (strC, px, py);
}
int n = iVector.size(); // Save the vector content to display later
iResult = new int[n];
for (int i = 0 ; i < n ; i++)
iResult[i] = ((Integer) iVector.elementAt (n-i-1)).intValue();
g2.setPaint (boxColor); g2.drawRect (dx, dy, w-2*dx, h-2*dy);
}
private void displayResults () {
StringBuffer sb = new StringBuffer ("Lattice: " + m1 + " \u00D7 " + m2 + " = " +
((lastCarry == 0) ? "" : (""+lastCarry)));
for (int k = 0 ; k < iResult.length ; k++)
sb.append ("" + iResult[k]);
// System.out.println (sb.toString());
JOptionPane.showMessageDialog (null, sb.toString(), "Lattice Multiplier",
JOptionPane.INFORMATION_MESSAGE);
}
public JPanel getButtonPanel () {
JPanel bp = new JPanel(new GridLayout (1,bNames.length));
for (int i = 0 ; i < bNames.length ; i++) {
JButton b = new JButton (bNames[i]);
b.addActionListener (this);
bp.add (b);
}
return bp;
}
private final static String[] bNames = {"Close", "Result"};
public void actionPerformed (ActionEvent e) {
String cmd = e.getActionCommand();
if (cmd.equals (bNames[0])) System.exit (0);
else if (cmd.equals (bNames[1])) displayResults();
}
public static void main (String[] args) {
JTextField tf1 = new JTextField (), tf2 = new JTextField();
JPanel num2m = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets (2,2,2,2);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = GridBagConstraints.RELATIVE;
gbc.anchor = GridBagConstraints.EAST;
JLabel
label = new JLabel ("Multiplicand", JLabel.TRAILING); num2m.add (label, gbc);
label = new JLabel ("Multiplier", JLabel.TRAILING); num2m.add (label, gbc);
gbc.gridx++;
gbc.weightx = 1.0f; num2m.add (tf1, gbc); num2m.add (tf2, gbc);
JFrame lf = new JFrame ("Lattice Multiplication");
if (JOptionPane.showConfirmDialog (lf, num2m, "Enter numbers to multiply",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE ) == JOptionPane.OK_OPTION) {
try {
int m = Integer.parseInt (tf1.getText()), n = Integer.parseInt (tf2.getText());
Lattice lattice = new Lattice (m, n, label.getFont());
lf.add (lattice.getButtonPanel(), "South");
lf.add (lattice, "Center");
lf.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
lf.pack();
lf.setVisible (true);
} catch (NumberFormatException nex) {
JOptionPane.showMessageDialog (lf, "Invalid numbers to multiply",
"Lattice Multiplier Error", JOptionPane.ERROR_MESSAGE);
System.exit (1);
}} else { System.exit (2);
}}}
this works for any set of numbers..2 digit multiplicand with 4 digit multiplier..etc..
if(numberM.length()!=numberN.length()){
int mLen = numberM.length();
int nLen = numberN.length();
if(numberM.length()>numberN.length()){
for(int i=0;i<mLen-nLen;i++){
numberN = "0" + numberN;
}
}
else
{
for(int i=0;i<nLen-mLen;i++){
numberM = "0" + numberM;
}
}
}
int result[] = new int[numberN.length()+numberM.length()];
String numberRN = new StringBuffer(numberN).reverse().toString();
String numberRM = new StringBuffer(numberM).reverse().toString();
//reversing the number
int n[] = new int[numberN.length()];
int m[] = new int[numberM.length()];
int size_of_array = 0;
for(int i=0;i<numberN.length();i++){
n[i] = Integer.parseInt((new Character(numberRN.charAt(i))).toString());
m[i] = Integer.parseInt((new Character(numberRM.charAt(i))).toString());
}
//System.out.println("Numbers are:");
//displayArray(n,"n");
//displayArray(m,"m");
size_of_array = (m.length*2)*2;
int soa = size_of_array;
int tempArray[] = new int[size_of_array*m.length];
//System.out.println("Size of tempArray ="+tempArray.length);
//placing the numbers in a single array
int oddValue =3;
int index = 0;
tempArray[index++] = 0;
for(int i=0;i<m.length;i++){
for(int j=0;j<n.length;j++){
//System.out.println("n["+j+"]="+n[j]+" and m["+i+"]="+m[i]);
tempArray[index++] = (n[j] * m[i]) % 10;
tempArray[index] = (n[j] * m[i]) / 10;
//System.out.println("tempArray["+(index-1)+"]="+tempArray[index-1]+" tempArray["+(index)+"]="+tempArray[index]);
index++;
}
//System.out.println("index before appending zero="+index);
size_of_array=(i+1)*soa;
index = size_of_array;
//System.out.println("index after appending zero="+index);
//index+=i+oddArray[i];
index+=i+oddValue;
oddValue++;
//System.out.println("After move index="+index);
}
//System.out.println("tempArray full");
//displayArray(tempArray,"tempArray");
//adding the numbers and also dealing with carry
int count=0;int ind = 0;int res = 0;int carry =0;int tempInd = 0;
for(int i=0;i<m.length*2;i++){
tempInd = ind;
for(int k=0;k<m.length;k++){
//System.out.println(tempArray[ind]+"---"+tempArray[ind+1]);
res = tempArray[ind] + tempArray[ind+1] + res + carry;
ind = ind + soa ;
carry = 0;
//System.out.println("res="+res+" ind="+ind+" soa="+soa);
}
//System.out.println("----------------");
result[count++] = res %10;
carry = res /10;
res = 0;
ind = tempInd+2;
}
//displayArray(result,"result");
displayResult(result,sign);
}
private static void displayResult(int[] result,String sign) {
System.out.print("The result is "+sign);
for(int i=result.length-1;i>=0;i--){
System.out.print(result[i]);
}
}
static void displayArray(int tempArray[],String name){
for(int k =0;k<tempArray.length;k++)
System.out.print(" "+name+"["+k+"]-"+tempArray[k]);
System.out.println("");
}