How to create a Kotlin Decimal Formatter - kotlin

I would like to create a decimal formatter that would display up to 2 decimal digits, with a given separator.
For example with separator ","
input -> output
3.0 -> "3"
3.1 -> "3,1"
3.14 -> "3,14"
3.141 -> "3,14"
3.149 -> "3,15"
I would like to do this in Kotlin, I guess I must use DecimalFormat but don't understand how to do so. Could you please help me?

The code below was tested against all your examples and seemed to work well:
val locale = Locale("en", "UK")
val symbols = DecimalFormatSymbols(locale)
symbols.decimalSeparator = ','
val pattern = "#.##"
val decimalFormat = DecimalFormat(pattern, symbols)
val format = decimalFormat.format(3.14)
println(format) //3,14
To set a specific separator in your DecimalFormat, you can use setDecimalSeparator.
Pay attention to the pattern as # means:
A digit, leading zeroes are omitted
You can obviously change the locale to your fitting.
More information here.

You indeed might use java.text.NumberFormat to achieve your goal. The following should work is quite close to your example Swift code.
// you can change the separators by providing a Locale
val nf = java.text.NumberFormat
.getInstance(java.util.Locale.GERMAN)
nf.minimumFractionDigits = 0
nf.maximumFractionDigits = 2
// you may want to change the rounding mode
nf.roundingMode = java.math.RoundingMode.DOWN
println(nf.format(0)) // 0
println(nf.format(1)) // 1
println(nf.format(1.2)) // 1,2
println(nf.format(1.23)) // 1,23
println(nf.format(1.234)) // 1,23
println(nf.format(12.345)) // 12,34

Related

How do I reduce the digits of an incoming multi-digit decimal number from API in Kotlin?

I'm getting a price value from an API but it's a multi-digits decimal number like 0.4785835398457. I want to reduce this number to 3 or 4 digits number like 0.3234 and I'm showing that value in a TextView. So First, I have to form this value and second I need to convert it to String. I tried that DecimalFormat method like at onBindViewHolder part of my RecyclerAdapter.
override fun onBindViewHolder(holder: CoinListViewHolder, position: Int) {
val df = DecimalFormat("#.###")
df.roundingMode= RoundingMode.CEILING //<-----Here
df.format(coinList[position].price_usd.also { holder.itemView.coinPrice.text = it.toString() }) // <----- And here
holder.itemView.coinTicker.text= coinList[position].asset_id
holder.itemView.setOnClickListener {
listener.onItemClick(coinList, position)
}
But it did not work. Please help me.
Thanks in advance.
You can just use a string formatter that uses the number of decimal places you want:
val number = 123.12345
"%.3f".format(number).run(::println)
>> 123.123
That basically converts a float value (f) to a string, to three significant digits (.3). The format spec is here but it's a bit complex.
As far as your code goes, this:
df.format(coinList[position].price_usd.also { holder.itemView.coinPrice.text = it.toString() })
is equivalent to this:
val price = coinList[position].price_usd
holder.itemView.coinPrice.text = price.toString()
df.format(price)
I'm assuming you want to format the price and then display it in the TextView (right now you're just formatting it and doing nothing with the result), which would be this:
df.format(coinList[position].price_usd)
.let { holder.itemView.coinPrice.text = it.toString() }
i.e. do the format, and then do this with the result
Try holder.itemView.coinPrice.text = df.format(coinList[position].price_usd)

How to convert digit to character in Kotlin?

I'm trying to find the simplest way to convert a digit (0..9) into the respective character '0'..'9' in Kotlin.
My initial attempt was to write the following code:
fun convertToCharacter() {
val number = 0
val character = number.toChar()
println(character)
}
Of course, after running, I quickly saw that this produces \u0000, and not '0' like I expected. Then, remembering from how to do this in Java, I modified the code to add '0', but then this would not compile.
fun convertToCharacter() {
val number = 0
val character = number.toChar() + '0'
println(character)
}
What is the appropriate way to convert a number into its respective character counterpart in Kotlin? Ideally, I'm trying to avoid pulling up the ASCII table to accomplish this (I know I can add 48 to the number since 48 -> '0' in ASCII).
val character = '0' + number
is the shortest way, given that the number is in range 0..9
Kotlin stdlib provides this function since 1.5.0.
fun Int.digitToChar(): Char
Returns the Char that represents this decimal digit. Throws an exception if this value is not in the range 0..9.
If this value is in 0..9, the decimal digit Char with code '0'.code + this is returned.
Example
println(5.digitToChar()) // 5
println(3.digitToChar(radix = 8)) // 3
println(10.digitToChar(radix = 16)) // A
println(20.digitToChar(radix = 36)) // K
Like you said, probably the easiest way to convert an Int to the Char representation of that same digit is to add 48 and call toChar():
val number = 3
val character = (number + 48).toChar()
println(character) // prints 3
If you don't want to have the magic 48 number in your program, you could first parse the number to a String and then use toCharArray()[0] to get the Char representation:
val number = 3
val character = number.toString().toCharArray()[0]
println(character) // prints 3
Edit: in the spirit of the attempt in your question, you can do math with '0'.toInt() and get the result you were expecting:
val number = 7
val character = (number + '0'.toInt()).toChar()
println(number) // prints 7
How about 0.toString() instead of 0.toChar() ? If you are specifically after single digits, then 0.toString()[0] will give you a Char type
You can use an extension like this:
fun Int.toReadableChar(): Char {
return ('0'.toInt() + this).toChar()
}
You can apply this to any other class you want :)
Example:
println(7.toReadableChar())
>> 7

How to get size of UInt() in chisel?

Maybe it's easy but I can't simply found how to get the bitsize of an UInt() value in Chisel ?
I know how to set a size by declaration :
val a = UInt(INPUT, 16)
But to get the 'a' size, is there a property like :
val size = a.?
Or :
val size = width(a)
A couple of things. First, looks like you are using Chisel 2 semantics. You should probably be using Chisel 3 semantics which means you should be writing
val a = Input(UInt(16.W))
The quick answer is you can get the width like:
val theWidth = if(io.in0.widthKnown) io.in0.getWidth else -1
or using match
val theWidth = io.in0.widthOption match {
case Some(w) => w
case None => -1 // you decide what you want the unknown case to be.
}
You now have the value of the width in the Scala variable theWidth which is an Int, the if or the match must be used because the width may, in principle, be undefined.
The longer answer is that you should be careful with wanting to do this. theWidth is evaluated at circuit generation time, if width inference is being used (which is usually the case if you are interrogating a chisel type for its width) you won't be able to see it because width inference is done after the circuit is elaborated and it is processed by the Firrtl compiler.
It's possible you should make the width you want to know a parameter to the circuit and use that instead of widthOption. Something like.
class X(ioWidth: Int) extends Module {
val io = IO( new Bundle {
val in0 = Input(UInt(ioWidth.W))
...
})
val reg = Reg(UInt((ioWidth * 2).W)) // using width parameter here.
...
}

How to convert toFixed(2) in Kotlin

What should I write in the place of area.toFixed(2)
fun main(args: Array<String>) {
val a = 20
val h = 30
val area = a * h / 2
println("Triangle area = ${area.toFixed(2)}")
}
I think you really meet a problem that how to convert Javascript code to Kotlin code. You need to ask the question clearly at next time, :). you can use String#format instead, for example:
println("%.2f".format(1.0)) // print "1.00"
println("%.2f".format(1.253)) // print "1.25"
println("%.2f".format(1.255)) // print "1.26"
AND the area is an Int which means it will truncates the precision, Kotlin doesn't like as Javascript use the numeric by default, so you should let a*h divide by a Double, then your code is like as below:
// v--- use a `Double` instead
val area = a * h / 2.0
println("Triangle area = ${"%.2f".format(area)}")

Elm: String.toFloat doesn't work with comma only with point - what to do?

I'm very new to elm and i want to do a simple mileage counter app.
If i get "1.2" (POINT) form input - String.toFloat returns in the OK branch with 1.2 as a number.
But if i get "1,2" (COMMA) form input, then String.toFloat returns in the Err branch with "You can't have words, only numbers!"
This pretty much works like a real time validator.
The code:
TypingInInput val ->
case String.toFloat val of
Ok success ->
{ model | inputValue = val, errorMessage = Nothing }
Err err ->
{ model | inputValue = val, errorMessage = Just "You can't have words, or spaces, only numbers!" }
.
Question: So how can i force String.toFloat of "1,2" to give me 1.2 the number?
Unfortunately the source for toFloat is hardcoded to only respect a dot as decimal separator. You can replace the comma with a dot in the string prior to passing it to toFloat as a workaround.
String.Extra.replace can be used for the simple string replacement.
The implementation of String.toFloat only supports a dot as a separator.
You should replace commas first before parsing the Float
Please see the example:
import Html exposing (text)
import String
import Regex
main =
"1,2"
|> Regex.replace Regex.All (Regex.regex ",") (\_ -> ".")
|> String.toFloat
|> toString
|> text -- 1.2
In JavaScript parseFloat doesn't support comma separator either.