blob: 81199e8efac47f22a9d613fa4a1af3c0cd66cfb6 [file] [log] [blame]
/**
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.android.healthconnect.controller.dataentries.units
import kotlin.math.roundToInt
object WeightConverter {
private const val POUNDS_PER_STONE = 14
private const val KG_PER_POUND = 0.453592
private const val KG_PER_STONE = 6.35029
private const val POUND_PER_KG = 2.20462
private const val STONE_PER_KG = 0.157473
private const val MAX_STONE_TO_KG_INPUT = Double.MAX_VALUE / KG_PER_STONE
private const val MAX_KG_TO_POUND_INPUT = Double.MAX_VALUE / POUND_PER_KG
/**
* Converts from kilograms to the provided units
*
* @param toUnit the units type to convert the passed in sourceKilograms (kg) to
* @param sourceKilograms the kg weight to convert to toUnit weight
* @return the sourceKilograms in toUnit weight units
*/
fun convertFromKilograms(toUnit: WeightUnit, sourceKilograms: Double): Double {
return when (toUnit) {
WeightUnit.KILOGRAM -> keepOneDecimal(sourceKilograms)
WeightUnit.POUND -> {
require(
!(sourceKilograms > MAX_KG_TO_POUND_INPUT ||
sourceKilograms < -MAX_KG_TO_POUND_INPUT)) {
"Kilogram input out of range: $sourceKilograms"
}
keepOneDecimal(sourceKilograms * POUND_PER_KG)
}
WeightUnit.STONE -> keepOneDecimal(sourceKilograms * STONE_PER_KG)
}
}
/**
* Converts from grams to the provided units
*
* @param toUnit the units type to convert the passed in sourceGrams (g) to
* @param sourceGrams the gram weight to convert to toUnit weight
* @return the sourceGrams in toUnit weight units
*/
fun convertFromGrams(toUnit: WeightUnit, sourceGrams: Double): Double {
return convertFromKilograms(toUnit, sourceGrams / 1000)
}
/**
* Converts from pounds to stones and pounds.
*
* @param weight the weight in pounds to convert
* @param significantDigits the number of significant digits to round the pounds to
*/
fun stonePoundsFromPounds(weight: Double, significantDigits: Int): StonePounds {
var stone = (weight / POUNDS_PER_STONE).toInt()
val pow = Math.pow(10.0, significantDigits.toDouble())
var pound = keepOneDecimal((weight % POUNDS_PER_STONE * pow).roundToInt() / pow)
if (pound == POUNDS_PER_STONE.toDouble()) {
pound = 0.0
stone++
}
return StonePounds(stone, pound)
}
private fun keepOneDecimal(weight: Double): Double {
return (weight * 10).roundToInt() / 10.0
}
}
/**
* Encapsulates the result of a conversion to UK imperial units; whole stones and fractional pounds.
*
* @param stone Stone value (14 pounds).
* @param pounds Pounds (between zero and 14).
*/
data class StonePounds(val stone: Int, val pounds: Double)