-1

The below code works accurate on int

public class Example {
    public static void main(String[] args) {

        int a = 3, b = 3, mul = 0;

        // mul = a * b //this should not be used

        for (int i = 1; i <= a; i++)
            mul = mul + b;

        System.out.println(a + "*" + b + "-->" + mul);
    }
}

output : 3*3-->9 Now this is perfect

But when i used double :

public class Example {
    public static void main(String[] args) {

        double a = 3.5, b = 3.5, mul = 0;

        // mul = a * b //this should not be used

        for (int i = 1; i <= a; i++)
            mul = mul + b;

        System.out.println(a + "*" + b + "-->" + mul);
    }
}

output:

3.5*3.5-->10.5 Now this is wrong since the correct answer of

3.5*3.5-->12.25

The problem is i need to multiply decimal values where as for loop wont support iteration over double value.

KishanCS
  • 1,357
  • 1
  • 19
  • 38
  • http://stackoverflow.com/questions/3971434/for-loop-increment-by-double ? –  Dec 29 '16 at 06:18
  • But why using a for loop ? There is other loop that could help you – AxelH Dec 29 '16 at 06:20
  • The reason "the loop won't support iteration over double value" is because _life won't support iteration over a fractional value_. Please explain just what you expected it to do--execute the loop body three and a half times? Just what the heck would that mean--even in a non-computer context? – ajb Dec 29 '16 at 06:31
  • Anyway, your loop is legal, but what it does is to let `i` take the values 1, 2, 3, 4, ..., as long as it's <= 3.5, then it quits. That means `i` will be 1, 2, and 3. So that's why your loop executes three times, and the value is multiplied by 3. As noted above, it makes absolutely no sense for it to try to execute the loop another half a time. – ajb Dec 29 '16 at 06:33

4 Answers4

3

Count decimal places, convert the numbers to integers, multiply via addition with loops, then reinsert your decimal place.

3.5 x 3.5 becomes 35 x 35, and then the decimal point is shifted 2 places to the left to give you your answer.

AJNeufeld
  • 8,526
  • 1
  • 25
  • 44
  • 2
    Actually, only one of the numbers (the one used to index the loop) needs to be normalized to integer. But then this approach breaks down because most floating point numbers are not exact representations of decimals, so you'll get something like 3.49999999999997 * 3.49999999999997 and overflow `int` and take forever. – Jim Garrison Dec 29 '16 at 06:22
  • You'll need to explain how to "count decimal places". If you start with a `double`, it may not be obvious how to do that. Also make sure it will work with a number like 3.4 that can't be represented exactly (unlike 3.5). – ajb Dec 29 '16 at 06:22
1

The explanation of such behavior is explained in this post - Java Double Multiplication explanation?

To resolve such issue it is best to use BigDecimal.

BigDecimal d1 = new BigDecimal("3.5");
BigDecimal d2 = new BigDecimal("3.5");
BigDecimal result = d1.multiply(d2);
System.out.printf("%s * %s = %s%n", d1, d2, result);
Community
  • 1
  • 1
0

STEPS:

  • Ignore the decimal point and convert those numbers to integers
  • Then Multiply them using additions (as you have done for integers)
  • Convert the answer to string and place the decimal at its place.

You will need String and StringBuilder for this.

Here is the code:

    double a = 3.5, b = 3.5;

    StringBuilder num1 = new StringBuilder(Double.toString(a));
    StringBuilder num2 = new StringBuilder(Double.toString(b));

    int indexOfDecimalPointFromBeginning_num1 = num1.indexOf(".");
    int indexOfDecimalPointFromBeginning_num2 = num2.indexOf(".");

    int decimalCounterNum1 = num1.length() - indexOfDecimalPointFromBeginning_num1 - 1;
    int decimalCounterNum2 = num2.length() - indexOfDecimalPointFromBeginning_num2 - 1;

    int decimalCountForResult = decimalCounterNum1 + decimalCounterNum2;

    String num1_withoutDecimal = num1.deleteCharAt(indexOfDecimalPointFromBeginning_num1).toString();
    String num2_withoutDecimal = num2.deleteCharAt(indexOfDecimalPointFromBeginning_num2).toString();

    int newNum1 = Integer.parseInt(num1_withoutDecimal);
    int newNum2 = Integer.parseInt(num2_withoutDecimal);

    int tempMul = 0;

    for (int i = 1; i <= newNum1; i++) {
        tempMul = tempMul + newNum2;
    }

    StringBuilder finalAnswer = new StringBuilder(Integer.toString(tempMul));
    finalAnswer.insert(finalAnswer.length() - decimalCountForResult, ".");

    Double finalAnswerInDouble = Double.parseDouble(finalAnswer.toString());
    System.out.println(a + "*" + b + " --> " + finalAnswer.toString());
Shubham
  • 247
  • 3
  • 11
  • If input is like 3.52528 and 3.52528 it goes out of integer .And throws exception – KishanCS Dec 29 '16 at 07:53
  • Exception in thread "main" java.lang.NumberFormatException: For input string: ".-278060800" at sun.misc.FloatingDecimal.readJavaFormatString(Unknown Source) at java.lang.Double.parseDouble(Unknown Source) at com.uks.javaskillup.day6.assignment_2.asd.main(asd.java:45) – KishanCS Dec 29 '16 at 07:53
  • Yes, You are right. As range of integer is small, it will throw the out of range exception for bigger values. In place of integer values (newNum1, newNum2, tempMul), Double values can be used to increase the range of integers. But precision can be lost there. – Shubham Dec 29 '16 at 12:32
0

You can convert your decimal values to integer with divide by 0,(0..)1. After operation you should divide by 1(0..).

Ex: 3,5*3,5 = (3,5/0,1)*(3,5/0,1)/100 = 35*35/100 = 12,25

Code;

 private double multiplication(double d1, double d2) {

        double divDiff1 = 1, divDiff2 = 1;

        while (d1 != Math.floor(d1)) {
            d1 = Double.valueOf(String.format("%.6f", d1 / 0.1));
            divDiff1 = divDiff1 / 0.1;
        }
        while (d2 != Math.floor(d2)) {
            d2 = Double.valueOf(String.format("%.6f", d2 / 0.1));
            divDiff2 = divDiff2 /0.1;
        }

        double mul = 0;
        for (int i = 1; i <= d1; i++)
            mul = mul + d2;

        return mul / divDiff2 / divDiff1;
    }

Call like below;

multiplication(2.5,1.6);
oyenigun
  • 587
  • 6
  • 15