Home > Mobile >  Efficient way of handling decimal places in floats - cause DecimalFormat and StringFormat depends on
Efficient way of handling decimal places in floats - cause DecimalFormat and StringFormat depends on

Time:08-11

I have encountered a problem when handling floats in an Android application

My case regards handling decimal places in kotlin Float, but I think it can be applied to Java.

Let's assume that I have an EditText which is a Number field in an Android app. This way, an user can just input an integer, and by an integer I mean a whole number, not the primitive data type. It's then passed to the code as a String so it doesn't matter.

private lateinit var weightText: EditText
private lateinit var heightText: EditText

Let's say that the user inputs two numbers - 120 and 174.

weightText = findViewById(R.id.etWeight)
heightText = findViewById(R.id.etHeight)

Then I am making an Body Mass Index calculation on them:

val bmiEquals = weight.toFloat() / ((height.toFloat() / 100) * (height.toFloat() / 100))

Easy.

But bmiEquals in this case is equal to 38.73967

Now I'd like to display the user this number with just two decimal places: 38.74

To achieve this I do:

val df = DecimalFormat("#.##")
val bmi2Digits = df.format(bmiEquals)

It was working fine in the Android emulator, but when I've tested the code on my physical device, I've encountered a problem here:

private fun displayResult(bmi: String) {

    when (bmi.toFloat()) {

I got an error cause bmi variable was not 38.74 but 38,74. I have researched a bit and it seems that this is caused by locale. In some countries, you divide floating point numbers using a dot, in some others - a comma. And DecimalFormat is used to format a number to a String.

I know that I could just use BigDecimals here, but I wonder if there is any way to handle this case while working on Floats.

Honestly? I have solved this problem using a silly solution:

when (bmi.replace(',', '.').toFloat()) {

But it is bothering me so hard... ;)

CodePudding user response:

you may always check which character is an decimal separator on running device using DecimalFormatSymbols.getInstance().getDecimalSeparator()

CodePudding user response:

try following round functionality from import kotlin.math.round

var bmi2Decimal = round(bmiEquals * 100)/100

bmi2Decimal is float and in this case, 100 is used to make it 2 decimal place

CodePudding user response:

You may use DecimalFormat with a specific locale.

val bmiEquals = 38.73967

Locale.setDefault(Locale.FRENCH)

val dfUS = DecimalFormat("#.##", DecimalFormatSymbols(Locale.US))
// or df.decimalFormatSymbols = DecimalFormatSymbols(Locale.US)
val dfResultUS = dfUS.format(bmiEquals)
println(dfResultUS) // output: 38.74

val dfLocale = DecimalFormat("#.##")
val dfResultLocale = dfLocale.format(bmiEquals)
println(dfResultLocale) // output: 38.74
  • Related