Adding and subtracting string numbers in Java - java

I'm supposed to create a program where a user enters two numbers that could be negative or positive and could contain decimal places or not. Theoretically, when you add say "256.78 + 78.6783" it is supposed to carry the one like a normal addition problem and finish the operation.
I have figured out how to add numbers of any length only when they are positive which took me FOREVER, but when I add negative numbers or even subtract the number I don't get the correct result. This is supposed to work with any set of two numbers that a user enters.
Here is my code so far, any suggestions?
P.S. I'm NOT allowed to convert these numbers to int's or double's before the operation so Parsing them is out of the question.
public class Number {
static Scanner kbd = new Scanner (System.in);
private String sign;
private String whole;
private String decimal;
private String fraction;
private static double firstNumber;
private static double secondNumber;
public static void main(String[] args) {
System.out.println("Please enter the first number: ");
firstNumber = kbd.nextDouble();
System.out.println("Next, enter the second number: ");
secondNumber = kbd.nextDouble();
Number x = new Number (firstNumber);
Number y = new Number (secondNumber);
Number sum = x.add(y);
System.out.println("x = " + x);
System.out.println("y = " + y);
System.out.println("x + y = " + sum);
Number subtract = x.subtract(y);
System.out.println("x - y = " + subtract);
}
public Number()
{
whole = "0";
decimal = "0";
sign = "+";
}
public String toString()
{
return sign + whole + "." + decimal;
}
public Number (double n)
{
whole = "0";
decimal = "0";
sign = "+";
String numString = new Double(n).toString();
if (numString.charAt(0) == '-') {
sign ="-";
numString = numString.substring(1);
}
int position = numString.indexOf(".");
if (position == -1)
whole = numString;
else
{
whole = numString.substring(0,position);
decimal = numString.substring(position+1);
fraction = "";
}
}
public Number add (Number RHS) {
this.fixWhole (RHS);
this.fixDecimal(RHS);
return this.addNum (RHS);
}
public Number subtract (Number RHS) {
this.fixWhole(RHS);
this.fixDecimal(RHS);
return this.subtractNum (RHS);
}
private void fixWhole (Number RHS) {
int firstWholeNum = this.whole.length();
int secondWholeNum = RHS.whole.length();
int difference = firstWholeNum - secondWholeNum;
if (difference > 0) {
for (int i = 1; i <= difference; i++)
RHS.whole = "0" + RHS.whole;
}
else if (difference < 0 ) {
difference = Math.abs(difference);
for (int i = 1; i <= difference; i++)
this.whole = "0" + this.whole;
}
}
private void fixDecimal (Number RHS ) {
int firstDecimalNum = this.decimal.length();
int secondDecimalNum = RHS.decimal.length();
int difference = firstDecimalNum - secondDecimalNum;
if (difference > 0) {
for (int i = 1; i <= difference; i++)
RHS.decimal = RHS.decimal + "0";
}
else if (difference < 0 )
{
difference = Math.abs(difference);
for (int i = 1; i <= difference; i ++)
this.decimal = this.decimal + "0";
}
}
private Number addNum (Number RHS ) {
Number sum = new Number();
sum.decimal = "";
int carry = 0;
int decimalNum = this.decimal.length();
for (int i = decimalNum - 1; i >= 0; i --) {
char c1 = this.decimal.charAt(i);
char c2 = RHS.decimal.charAt(i);
int tempSum= (c1 - 48) + (c2 - 48) + carry;
carry = tempSum/ 10;
int sumDigit = tempSum % 10;
sum.decimal = (char) (sumDigit + 48) + sum.decimal;
}
sum.whole = "";
int wholeNum = this.whole.length();
for (int i = wholeNum - 1; i >= 0; i --) {
char c1 = this.whole.charAt(i);
char c2 = RHS.whole.charAt(i);
int tempSum = (c1 - 48) + (c2 - 48 ) + carry;
carry = tempSum / 10;
int sumDigit = tempSum % 10;
sum.whole = (char) (sumDigit + 48) + sum.whole;
}
if (carry != 0)
sum.whole = "1" + sum.whole;
return sum;
}
private Number subtractNum (Number RHS ) {
Number sum = new Number();
sum.decimal = "";
int carry = 0;
int decimalNum = this.decimal.length();
for (int i = decimalNum - 1; i >= 0; i --) {
char c1 = this.decimal.charAt(i);
char c2 = RHS.decimal.charAt(i);
int tempSum= (c1 - 48) - (c2 - 48) - carry;
carry = tempSum/ 10;
int sumDigit = tempSum % 10;
sum.decimal = (char) (sumDigit - 48) + sum.decimal;
}
sum.whole = "";
int wholeNum = this.whole.length();
for (int i = wholeNum - 1; i >= 0; i --) {
char c1 = this.whole.charAt(i);
char c2 = RHS.whole.charAt(i);
int tempSum = (c1 - 48) - (c2 - 48 ) + carry;
carry = tempSum / 10;
int sumDigit = tempSum % 10;
sum.whole = (char) (sumDigit + 48) + sum.whole;
}
if (carry != 0)
sum.whole = "1" + sum.whole;
return sum;
}
}

take both the numbers as strings and store the signs into the sign string into the corresponding Numbers objects and call your method like
System.out.println("Please enter the first number: ");
firstNumber = kbd.nextString();
System.out.println("Next, enter the second number: ");
secondNumber = kbd.nextString();
Number x = new Number (firstNumber.substring(1),firstNumber.charAt(0));
Number y = new Number (secondNumber.substring(1),secondNumber.charAt(0));
/*convert the firstNumber.substring(1) and secondNumber.substring(1) to doubles using Double.parseDouble()*/
public String doTheOperation(Number other){
if(this.sign.equals(otherNumber.sign)){
/*simply the double values and put the sign*/ in front of it and return it
}
else{
do the simple double subtraction and by looking at your code i believe you can find out the bigger double among them
}
}

Related

Why does my loop increment 1 over the value needed?

This is my first CS class ever, and I'm trying to learn everything the best that can. In this loop I am trying to find valid mastercard numbers using Luhn's formula. The program works, but it's been bugging me that my final for loop outputs 1 number over the correct value, unless I subtract 1 from z after the loop finishes iterating. For example: if the sum = 56 , then z would = 5 , when the correct answer would be 4. How can I fix this going forward?
import java.util.Random;
import java.util.Scanner;
import java.util.concurrent.ThreadLocalRandom;
public class MCGenerator {
public static void main(String [] args) {
Scanner scnr = new Scanner(System.in);
Random rand = new Random();
System.out.print("How many Mastercard numbers would you like to generate? ");
int quantity = scnr.nextInt();
int x;
int use;
int range;
int appendI;
Long appendL;
String firstDigits;
String append;
String preliminary;
int y;
int c;
int sum;
int z;
int findDigit;
String lastNum;
String cardNumber;
System.out.println("\nHere you go, have fun: ");
for(x = 0; x < quantity; x++ ) {
use = rand.nextInt(2 - 1 + 1) +1;
if(use == 1) {
range = rand.nextInt(55 - 51 + 1) + 51;
}
else {
range = rand.nextInt(272099 - 222100 +1) + 222100;
}
if(range < 56) {
appendL = ThreadLocalRandom.current().nextLong(1000000000000L, 10000000000000L);
append = String.valueOf(appendL);
}
else {
appendI = rand.nextInt(999999999 - 100000000 + 1) + 100000000;
append = String.valueOf(appendI);
}
firstDigits = String.valueOf(range);
preliminary = firstDigits + append;
for(y = 0, sum = 0; y < 15; y++ ) {
c = preliminary.charAt(y) - '0';
if(y % 2 == 0){
c *= 2;
}
if(c > 9) {
c -= 9;
}
sum += c;
}
for(z = 0, findDigit = sum; findDigit > 0; z++){
findDigit = sum + z;
findDigit %= 10;
}
z -= 1;
lastNum = String.valueOf(z);
cardNumber = preliminary + lastNum;
System.out.println(cardNumber);
}
}
}

How to add two very large numbers irrespective of their size in Java without using BigInteger data type?

I need to add two very large numbers without using BigInteger. I am taking two string parameters but the below code only works with strings of equal length otherwise it throws IndexOutOfBoundsException. How can I fix that by adding big numbers irrespective of their length?
public static String add(String a, String b) {
int carry = 0;
String result = "";
for (int i = a.length() - 1; i >= 0; i--) {
int digitA = a.charAt(i) - 48;
int digitB = b.charAt(i) - 48;
int resultingNumber = digitA + digitB + carry;
if (resultingNumber >= 10) {
result = (resultingNumber % 10) + result;
carry = 1;
} else {
result = resultingNumber + result;
carry = 0;
}
}
if (carry > 0) {
result = carry + result;
}
return result;
}
There is no need to pad any of the parameters with zeroes. Also, for better performance, don't use String + String.
Create a char[] for the result. Since the result can be 1 longer than the longest input, create it at that size.
Then iterate from end of input strings, setting each character in the result.
Then eliminate any leading zeroes, resulting from inputs not overflowing or from inputs having leading zeroes.
Finally, create a String from the char[] using the String(char[] value, int offset, int count) constructor.
Like this:
public static String add(String a, String b) {
int i = a.length();
int j = b.length();
int k = Math.max(i, j) + 1; // room for carryover
char[] c = new char[k];
for (int digit = 0; k > 0; digit /= 10) {
if (i > 0)
digit += a.charAt(--i) - '0';
if (j > 0)
digit += b.charAt(--j) - '0';
c[--k] = (char) ('0' + digit % 10);
}
for (k = 0; k < c.length - 1 && c[k] == '0'; k++) {/*Skip leading zeroes*/}
return new String(c, k, c.length - k);
}
Test
public static void main(String[] args) {
test("1234", "2345"); // test equal-sized inputs, no carry-over
test("12345", "12345"); // test equal-sized inputs, with carry-over
test("54321", "54321"); // test equal-sized inputs, longer result
test("99999", "99999"); // test max result
test("5", "1234"); // test odd-sized inputs, no carry-over
test("5", "12345"); // test odd-sized inputs, with carry-over
test("1", "99999"); // test with a carry-over to longer result
test("001", "00002"); // test leading zeroes in input are eliminated
test("000", "00000"); // test leading zero removal leaves 1 zero
}
public static void test(String a, String b) {
// Test add is commutative, i.e. a+b = b+a
System.out.printf("%s + %s = %s = %s%n", a, b, add(a, b), add(b, a));
}
Output
1234 + 2345 = 3579 = 3579
12345 + 12345 = 24690 = 24690
54321 + 54321 = 108642 = 108642
99999 + 99999 = 199998 = 199998
5 + 1234 = 1239 = 1239
5 + 12345 = 12350 = 12350
1 + 99999 = 100000 = 100000
001 + 00002 = 3 = 3
000 + 00000 = 0 = 0
You can prepend the shorter string with zeros to make it match the length of the other number:
private static String leftPad(String s, int length) {
if (s.length() >= length)
return s;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length - s.length(); i++)
sb.append("0");
return sb.toString() + s;
}
public static String add(String originalA, String originalB) {
int maxLength = Math.max(originalA.length(), originalB.length());
String a = leftPad(originalA, maxLength);
String b = leftPad(originalB, maxLength);
... rest of your method
You can left pad with zeroes the strings like this:
int longestString = Math.max(a.length(), b.length());
a = String.format("%1$" + longestString + "s", a).replace(' ', '0');
b = String.format("%1$" + longestString + "s", b).replace(' ', '0');
This will add leadings spaces to fill the "gap" and then replace them with zeroes.
Class:
public class Mission09 {
public static void main(String[] args) {
System.out.println(add("1", "1333"));
}
public static String add(String a, String b) {
int carry = 0;
String result = "";
int longestString = Math.max(a.length(), b.length());
a = String.format("%1$" + longestString + "s", a).replace(' ', '0');
b = String.format("%1$" + longestString + "s", b).replace(' ', '0');
for (int i = a.length() - 1; i >= 0; i--) {
int digitA = a.charAt(i) - 48;
int digitB = b.charAt(i) - 48;
int resultingNumber = digitA + digitB + carry;
if (resultingNumber >= 10) {
result = (resultingNumber % 10) + result;
carry = 1;
} else {
result = resultingNumber + result;
carry = 0;
}
}
if (carry > 0) {
result = carry + result;
}
return result;
}
}
I/O:
System.out.println(add("1", "1333"));
1334
System.out.println(add("12222", "1333"));
13555

Luhn formula implementation in Java

I'm trying to implement a luhn formula in my java servlet application. I tried other 'valid' credit cards numbers scattering in the internet and didn't work. I just want to know if I got it correctly. Any help would be appreaciate!
public static boolean luhn(String input){
char[] creditCard = input.toCharArray();
int checkSum = 0;
boolean alternate = false;
for (int i = creditCard.length - 1; i >= 0; i --){
int m = (int)Integer.parseInt(Character.toString(creditCard[i]));
if (alternate){
m *= 2;
if (m > 9){
m = (m & 10) + 1;
}
}
checkSum += m;
alternate = true;
}
if ( (checkSum % 10) == 0){
return true;
}else{
return false;
}
}
here the working code
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
boolean repeat;
List<Integer> digits = new ArrayList<Integer>();
do {
repeat = false;
System.out.print("Enter your Credit Card Number : ");
String input = in.next();
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (c < '0' || c > '9') {
repeat = true;
digits.clear();
break;
} else {
digits.add(Integer.valueOf(c - '0'));
}
}
} while (repeat);
int[] array = new int[digits.size()];
for (int i = 0; i < array.length; i++) {
array[i] = Integer.valueOf(digits.get(i));
}
boolean valid = check(array);
System.out.println("Valid: " + valid);
}
to check for luhn algo
public static boolean check(int[] digits) {
int sum = 0;
int length = digits.length;
for (int i = 0; i < length; i++) {
// get digits in reverse order
int digit = digits[length - i - 1];
// every 2nd number multiply with 2
if (i % 2 == 1) {
digit *= 2;
}
sum += digit > 9 ? digit - 9 : digit;
}
return sum % 10 == 0;
}
or a more refracted program might be as below
import java.util.Scanner;
public class Luhn {
private static Scanner input;
public static void main(String... args) {
input = new Scanner(System.in);
System.out.print("Enter number to validate:\n");
String pnr = input.nextLine();
boolean result = luhn(pnr);
printMessage(result);
input.close();
}
static boolean luhn(String pnr){
// this only works if you are certain all input will be at least 10 characters
int extraChars = pnr.length() - 10;
if (extraChars < 0) {
throw new IllegalArgumentException("Number length must be at least 10 characters!");
}
pnr = pnr.substring(extraChars, 10 + extraChars);
int sum = 0;
for (int i = 0; i < pnr.length(); i++){
char tmp = pnr.charAt(i);
int num = tmp - '0';
int product;
if (i % 2 != 0){
product = num * 1;
}
else{
product = num * 2;
}
if (product > 9)
product -= 9;
sum+= product;
}
return (sum % 10 == 0);
}
private static void printMessage(boolean valid) {
if (valid){
System.out.print("Valid!\r");
}
else{
System.out.print("Invalid!");
}
}
}

adding and subtracting strings in Java

I need some help on a program i'm supposed to create. i'm supposed to create a program that reads two strings of any length that are user inputted and it subtracts or adds them together. i'm NOT allowed to convert these strings into numbers before the operation. this is what I got so far.My teacher mentioned something like converting the strings into uni-code to add and subtract them but i have no idea how to do it as we haven't even learned uni-code. HERE IS MY CODE:
import java.util.Scanner;
public class Number {
private char Sign;
private String Whole;
private String Fraction;
public static void main(String[] args) {
Scanner Keyboard = new Scanner (System.in);
System.out.println("This program adds or subtracts numbers of any lengths, please add two numbers: ");
String num1 = Keyboard.nextLine();
System.out.println("Enter the second number: ");
String num2 = Keyboard.nextLine();
String sum = " ";
int length = num1.length();
int carry = 0;
public Number Add(Number RHS) {
for (int i = length -1 ; i >= 0; i--) {
char c1 = num1.charAt(i);
char c2 = num2.charAt(i);
int tempSum = (c1 - 48) + (c2 - 48) + carry;
carry = tempSum / 10;
int sumDigit = tempSum % 10;
sum = (char) (sumDigit + 48) + sum;
if (carry == 1) {
sum = "1" + sum;
}
}
}
}
public Number (double n) {
Whole = " ";
Fraction = " ";
if (n >= 0) {
Sign = '+';
}
else
{
Sign = '-';
n = Math.abs(n);
String numString = new Double(n).toString();
int position = numString.indexOf(".");
}
}
}
public static String add(String as, String bs){
ArrayList<String> BigNum = new ArrayList<>();
int m = as.length()-1;
int n = bs.length()-1;
int min = m > n ? n : m ;
int max = 0;
String s;
if(n > m){
s = bs;
max = n;
}else{s = as ; max = m;}
Integer carry = 0;
while(true){
int a = Integer.parseInt(Character.toString(as.charAt(m)));
int b = Integer.parseInt(Character.toString(bs.charAt(n)));
Integer c = a + b + carry;
if(c > 9){
carry = 1;
c %=10;
}else carry = 0;
BigNum.add(c.toString());
n--; m--; min--; max--;
if ( min < 0 ) {
if(carry !=0 && max < 0 )
BigNum.add(carry.toString());
break;
}
}
Integer c = carry;
while(max >= 0) {
c += Integer.parseInt(Character.toString(s.charAt(max)));
BigNum.add(c.toString());
c = 0;
max--;
}
String s2 = "";
for (int i = BigNum.size()-1; i >= 0; i--) {
s2 +=BigNum.get(i);
}
return s2;
}

nested for() loops && using the "i" count from the first loop in the second so i loops just once using the value?

i am trying to not import the math class to use but i am still trying to estimate the constant "e". it is said e= 1+(1/1!)+(1/2!)+(1/3!)+(1/4!)+(1/5!)+.....
these are what i have int at the top
String userInput;
int uIp; // this converts the string into int type
double e = 2;
then i ask some questions then i check to see not zero to exit and non negative to continue
While(uIp >0){
final int endTheLoop = 15;
int factorialNumber = 1;
double e2TheUserInput=0;
for(int i = 2; i < endTheLoop; i++){
for(int j = 1; j < i; j++){
factorialNumber = ((i - 1) * factorialNumber);
}
e = (1/factorialNumber) + e;
e2TheUserInput = Math.pow(e,uIp);
}
}
You are doing integer division(but e is a double right?):
e = (1/factorialNumber) + e;
Correct that to:
e = (1.0/(double)factorialNumber) + e;
It was counting all the loops, but changes are zero according to the integer division. :)
e= 2+(0)+(0)+(0)+(0)+.....
I am not sure what your code is trying to do but if you want to compute exp(x) this is how I would do it.
public static void main(String... args) {
for (int i = -4; i <= 4; i++)
System.out.println(i + ": " + exp(i) + " cf " + Math.exp(i));
}
private static double exp(double d) {
if (d < 0)
return 1 / exp(-d);
double e = 1, term = 1;
for (int i = 1; i < 20 || term > e * 1e-16; i++) {
term *= d / i;
e += term;
}
return e;
}
For large exponents, it more efficient to evaluate the integral powers without using a taylor series.
public static final double E = 2.7182818284590452354;
private static double exp(double d) {
if (d < 0)
return 1 / exp(-d);
long num = (long) d;
double numE = 1;
double mult = E;
while (num > 0) {
if ((num & 1) != 0)
numE *= mult;
num >>>= 1;
mult *= mult;
}
double fract = d - (long) d;
double fractE = 1, term = 1;
for (int i = 1; i < 20; i++) {
term *= fract / i;
fractE += term;
}
return numE * fractE;
}

Categories

Resources