How to get 1 decimal Float in swift [duplicate] - objective-c

This question already has answers here:
Precision String Format Specifier In Swift
(31 answers)
Closed 8 years ago.
I want to extract 1 decimal float number from existing float number.
I have done this in Objective-C:
Make a float only show two decimal places
Any idea how to make it happen in Swift?

You can make the same in swift :
var formatter : NSString = NSString(format: "%.01f", myFloat)
Or like you want in one line :
println("Pro Forma:- \n Total Experience(In Years) = "+(NSString(format: "%.01f", myFloat)))
This work too with the old NSLog (but prefer println) :
NSLog("Pro Forma:- \n Total Experience(In Years) = %.01f \n", myFloat)

You can try this
var experience = 10.25
println("Pro Forma:- \n Total Experience(In Years) = " + NSString(format: "%.01f", experience))

How about an infix operator?
// Declare this at file level, anywhere in you project.
// Expressions of the form
// "format string" %% doubleValue
// will return a string. If the string is not a well formed format string, you'll
// just get the string back! If you use incorrect format specifiers (e.g. %d for double)
// you'll get 0 as the formatted value.
operator infix %% { }
#infix func %% (format: String, value: Double) -> String {
return NSString(format:format, value)
}
// ...
// You can then use it anywhere
let experience = 1.234
println("Pro Forma:- \n Total Experience(In Years) = %.01f" %% experience)
I've tried to do it with generics, but I can't see how. To make it work with multiple types, just overload it for those types - e.g.
operator infix %% { }
#infix func %% (format: String, value: Double) -> String {
return NSString(format:format, value)
}
#infix func %% (format: String, value: Float) -> String {
return NSString(format:format, value)
}
#infix func %% (format: String, value: Int) -> String {
return NSString(format:format, value)
}

Related

Most idiomatic way to convert a Float value to a string without a decimal point in Kotlin

I'd like to convert a Float value to a String, but without a decimal point. For example, for the following code:
fun toDecimalString(value: Float): String {
// TODO
}
fun main() {
println("Result: ${toDecimalString(1.0f)}")
println("Result: ${toDecimalString(1.999999f)}")
println("Result: ${toDecimalString(20.5f)}")
}
I'd like the expected output to be:
1
1
20
As #Tenfour04 said, the answer is to first convert to an integer, by using .toInt(), which only leaves the digits left of the decimal point, and then convert to string using .toString().
.toInt().toString()
By converting to an Int before turning the input to a string, all decimal point values are dropped, e.g.:
fun toDecimalString(value: Float): String = "${value.toInt()}"

How do we round only if the number is with .0 in decimal

Ex 10.0 = 10
10.3 = 10.3
10.7 = 10. 7
Looking for a convenient way from Kotlin Standard library
You can use the following function:
fun removeTrailingZeros(num: String): String {
if(!num.contains('.')) // Return the original number if it doesn't contain decimal
return num
return num
.dropLastWhile { it == '0' } // Remove trailing zero
.dropLastWhile { it == '.' } // Remove decimal in case it's the last character in the resultant string
}
You can verify the code here
You can try this:
double number = 23.471;
if (number % 1 != 0)
{
//round off here
System.out.print ("Decimal");
}
else
{
System.out.print ("Integer");
}
If you want to get a string, the easiest way is to work with a string like num.toString().replace(".0",""). For numbers conversion does not make sense since the resulting type is different for different inputs.

Kotlin convert hex string to ByteArray

I have this string:
val s = "00b44a0bc6303782b729a7f9b44a3611b247ddf1e544f8b1420e2aae976003219175461d2bd7" +
"6e64ba657d7c9dff6ed7b17980778ec0cbf75fc16e52463e2d784f5f20c1691f17cdc597d7a514108" +
"0809a38c635b2a62082e310aa963ca15953894221ad54c6b30aea10f4dd88a66c55ab9c413eae49c0b" +
"28e6a3981e0021a7dcb0759af34b095ce3efce78938f2a2bed70939ba47591b88f908db1eadf237a7a" +
"7100ac87130b6119d7ae41b35fd27ff6021ac928273c20f0b3a01df1e6a070b8e2e93b5220ad0210400" +
"0c0c1e82e17fd00f6ac16ef37c3b6153d348e470843a84f25473a51f040a42671cd94ffc989eb27fd42" +
"b817f8173bfa95bdfa17a2ae22fd5c89dab2822bcc973b5b90f8fadc9b074cca8f9365b1e8994ff0bda48" + "b1f7498cce02d4e794915f8a4208de3eaf9fbff5"
Which is hexadecimal notation of bytes, hardcoded in as string format.
I need this thing as a bytearray, importantly, not the ASCII representation of it, actually the hexadecimal values that is represents.
All the kotlin methods I can find, such as:
val b = s.encodeToByteArray()
Seem to be taking the actual ASCII value of the string, and converting it to a bytearray.
How do I create a bytearray directly from the values in this string?
You can handle it like this:
fun String.decodeHex(): ByteArray {
check(length % 2 == 0) { "Must have an even length" }
return chunked(2)
.map { it.toInt(16).toByte() }
.toByteArray()
}
Split the string into 2-character pairs, representing each byte.
Parse each hex pair to their integer values.
Convert the parsed Ints to Bytes.
My other answer is the simplest way, but it creates two intermediate lists - a list of strings and a list of bytes - before it creates the byte array. Here are two slightly more complex versions that are more efficient.
This version uses sequences to take advantage of lazy evaluation. It still produces a string for every byte, but uses no intermediate lists.
fun String.decodeHex(): ByteArray {
check(length % 2 == 0) { "Must have an even length" }
val byteIterator = chunkedSequence(2)
.map { it.toInt(16).toByte() }
.iterator()
return ByteArray(length / 2) { byteIterator.next() }
}
This version uses the JDK's java.lang.Integer.parseInt function. It creates the ByteArray directly with no intermediate data-structures.
fun String.decodeHex(): ByteArray {
check(length % 2 == 0) { "Must have an even length" }
return ByteArray(length / 2) {
Integer.parseInt(this, it * 2, (it + 1) * 2, 16).toByte()
}
}

Why single char and "single char String" not equal when converted to long (.toLong())

I wanted to sum the digits of Long variable and add it to the variable it self, I came with the next working code:
private fun Long.sumDigits(): Long {
var n = this
this.toString().forEach { n += it.toString().toLong() }
return n
}
Usage: assert(48.toLong() == 42.toLong().sumDigits())
I had to use it.toString() in order to get it work, so I came with the next test and I don't get it's results:
#Test
fun toLongEquality() {
println("'4' as Long = " + '4'.toLong())
println("\"4\" as Long = " + "4".toLong())
println("\"42\" as Long = " + "42".toLong())
assert('4'.toString().toLong() == 4.toLong())
}
Output:
'4' as Long = 52
"4" as Long = 4
"42" as Long = 42
Is it a good practice to use char.toString().toLong() or there is a better way to convert char to Long?
Does "4" represented by chars? Why it is not equal to it char representation?
From the documentation:
class Char : Comparable (source) Represents a 16-bit Unicode
character. On the JVM, non-nullable values of this type are
represented as values of the primitive type char.
fun toLong(): Long
Returns the value of this character as a Long.
When you use '4' as Long you actually get the Unicode (ASCII) code of the char '4'
As mTak says, Char represents a Unicode value. If you are using Kotlin on the JVM, you can define your function as follows:
private fun Long.sumDigits() = this.toString().map(Character::getNumericValue).sum().toLong()
There's no reason to return Long rather than Int, but I've kept it the same as in your question.
Non-JVM versions of Kotlin don't have the Character class; use map {it - '0'} instead.

Can you map/reduce a String into an Int?

I was solving a problem on codeforces in which I had to sum up the digits of a big number (it can have up to 100k digits) and I'd have to repeat that process until there is only one digit left and count the number of times I did that and I came up with a working solution, however I'd like to know if some things could have been done in a more "Kotlin-ish like way", so given:
fun main(args: Array<String>) {
println(transform(readLine()!!))
}
fun transform(n: String): Int {
var count = 0
var sum : Int
var s = n
while(s.length > 1) {
sum = (0 until s.length).sumBy { s[it].toInt() - '0'.toInt() }
s = sum.toString()
count++
}
return count
}
sum = (0 until s.length).sumBy { s[it].toInt() - '0'.toInt() } is there a way to I guess map the sum of digits in the string to the sum variable, or in general a better approach than the one I used?
When converting a Char to an Int it converts it to the ASCII value so I had to add "-'0'.toInt()" is there a faster way (not that it's too much to write, asking out of curiosity)?
How to make the String n mutable without creating a new String s and manipulating it? Or is that the desired (and only) way?
P.S. I'm a beginner with Kotlin.
When converting a Char to an Int it converts it to the ASCII value so I had to add "-'0'.toInt()" is there a faster way (not that it's too much to write, asking out of curiosity)?
You can simply write s[it] - '0', because subtracting Chars in Kotlin already gives you an Int:
public class Char ... {
...
/** Subtracts the other Char value from this value resulting an Int. */
public operator fun minus(other: Char): Int
...
}
But why are looping over the indexes when you could loop over the Chars directly?
sum = s.sumBy { it - '0' }
This is a functional (and recursive) style to solve it:
private fun sum(num: String, count: Int) : Int {
return num
//digit to int
.map { "$it".toInt() }
//sum digits
.sum()
//sum to string
.toString()
//if sum's length is more than one, do it again with incremented count. Otherwise, return the current count
.let { if (it.length > 1) sum(it, count + 1) else count }
}
And you call it like this:
val number = "2937649827364918308623946..." //and so on
val count = sum(number, 0)
Hope it helps!