Reputation: 1987
I need to multiply two numbers (for example, A and B) and return the result (A*B).
Condition:
number A: Any number between 0 to Long.MAX_VALUE ( i.e., 0 <= A <= 9,223,372,036,854,775,807)
number B: Any number between 0 to 10000.0000000000) // Remember 'B' will be a decimal number with upto 10 decimal places
If the result of (A * B) contains decimal, then, round up to the next higher integer. for example,
I wrote a simple function as mentioned but it is giving me strange result!! Can you please correct me why the function is failing?
static long multiply(long A, float B)
{
long result = (long) Math.ceil(A * B);
return result;
}
public static void main(String args[])
{
System.out.println(multiply(10L, 1.11F)); // 10 x 1.11 => 11.1 => 12 [PASS]
System.out.println(multiply(10L, 1.17F)); //10 x 1.17 => 11.7 => 12 [PASS]
System.out.println(multiply(Long.MAX_VALUE, 1.11F)); // 9223372036854775807 x 1.11 => 9223372036854775807 [PASS]
System.out.println(multiply(9999999L, 9.9999F)); // 9999999 x 9.9999 => 99,998,990.0001 => 99,998,991 [FAIL]
// I am getting 99998992, instead of 99998991 !!
System.out.println(multiply(4611686018427387908L, 1.0F)); // 4611686018427387908L x 1 => 4611686018427387908 [FAIL]
// I am getting 4611686018427387904 instead of 4611686018427387908
System.out.println(multiply(96113850L, 1.0F)); // 96113850 x 1 => 96113850 [FAIL]
// I am getting 96113848 instead of 96113850
}
Last 3 test cases are failing. Please let me know how to correct it?
Thank you.
Upvotes: 1
Views: 712
Reputation: 21586
Use BigDecimal to calculate and round in the Decimal number system with almost infinite range:
static long multiply(long A, float B)
{
return new BigDecimal(A)
.multiply(new BigDecimal(B))
.max(new BigDecimal(Long.MAX_VALUE)
.setScale(0, RoundingMode.UP)
.longValue();
}
Upvotes: 3
Reputation: 159114
First, if "'B' will be a decimal number with upto 10 decimal places", then it needs to be a double
, not a float
.
To prevent loss of precision during the calculation, it needs to be done using BigDecimal
.
static long multiply(long a, double b) {
if (a < 0 || b < 0)
throw new IllegalArgumentException("Negative value not allowed");
BigDecimal result = BigDecimal.valueOf(a)
.multiply(BigDecimal.valueOf(b))
.setScale(0, RoundingMode.UP);
return (result.compareTo(BigDecimal.valueOf(Long.MAX_VALUE)) < 0
? result.longValue() : Long.MAX_VALUE);
}
Test
System.out.println(multiply(10L, 1.11)); // 12
System.out.println(multiply(10L, 1.17)); // 12
System.out.println(multiply(Long.MAX_VALUE, 1.11)); // 9223372036854775807
System.out.println(multiply(9999999L, 9.9999)); // 99998991
System.out.println(multiply(4611686018427387908L, 1.0)); // 4611686018427387908
System.out.println(multiply(96113850L, 1.0)); // 96113850
Upvotes: 5