I'm trying to multiply two crypto currencies together, their numbers are for example, 0.00200
and 0.00300
. I've defined them as floats, I've also tried doubles and big decimals. But I'm struggling to get the output I'm expecting.
Here's the test:
class MultiplyDecimalTest {
@Test
fun `test can multiply two decimal integers`() {
val a = 0.00200
val b = 0.00400
val expected = 0.00800
val actual = multiplyDecimal(a, b).toDouble()
assertEquals(expected, actual)
}
}
Current function:
fun multiplyDecimal(a: Double, b: Double): BigDecimal {
return BigDecimal(b).multiply(BigDecimal(a))
}
I'm new to Kotlin/Java, so I suspect I'm using the wrong type of integer perhaps.
The actual outcome is: 8.0E-6
- I understand the E-6 is an exponent, I'd like to be able to format it like the original values as well.
A key part of BigDecimal
is that you must use it literally the whole way through: passing Double
into BigDecimal
destroys any benefit you would get from BigDecimal
.
You must use constructor taking a String
, BigDecimal("0.00200")
and BigDecimal("0.00400")
, with the quotes. Then call multiply
on them. You must not call doubleValue()
on the result.
Equality testing on BigDecimal
also adds complications, requiring exactly the same scale. Consider using compareTo
like this, assertTrue(expected.compareTo(actual) == 0)
.
Another issue: Your math is incorrect. 0.00200 * 0.00400 = 0.000008 rather than 0.00800.
Example code using only BigDecimal
while avoiding Double
. In Java syntax. Corrected your inputs.
var a = "0.002000" ;
var b = "0.004000" ;
var expected = "0.000008" ;
var actual = new BigDecimal( a ).multiply( new BigDecimal( b ) ) ;
actual = actual.setScale( new BigDecimal( a ).scale() ) ; // Set scale of result to match the scale of inputs.
boolean matching = actual.equals( new BigDecimal( expected ) ) ;
See this code run live at IdeOne.com.
actual: actual: 0.000008
matching: true