I’m doing some image manipulation stuff, and UBytes are great, thank you!
I have to do some math on them, and noticed that “toUByte” doesn’t seem like a first-class citizen. For example, if I do some math, end up with a double, I have to first .toUInt() or .toInt() before I can toUByte().
Why is .toUInt more cool than .toUByte? Just an oversight?
FR: All the toUnsigned converters exist in all the same places that their toSigned siblings exist.
Conversion between floats and bytes are first-level citizen in the platform. Meaning Kotlin does not do it itself, but delegates to JVM. This way, it is a general contract for any Number to be able to cast to Byte. UByte is not a Number yet. Which leads to second point.
Unsigned numbers are still in experimental phase, so library developers probably do not want them to be fully and seamlessly integrated in the code yet, because there could be problems later.
I’ve temporarily given up on Unsigned. Extra conversion steps, different supporting functions and not serializable outweighed the space and speed advantages (in my particular case).
Same places that Double.toByte() are useful. myUByte = (myUByte.toDouble() * myPercentDoubleForChannelFiltering).toUByte()
(I’m masking a luminance channel of UBytes/pixels by multiplying by a 0.0…1.0 percent)
Totally can do that. The reason for this thread was for me to get a better understanding of the “expected contracts” that Kotlin provides.
For example,
Q: “Does every Number have toOtherNumberType()?” A: nope, Unsigned is special. But maybe someday.
Q: “Should I expect toUByte() every place there is toByte()?” A: not always. But I should be able to bounce through toByte().toUByte() in those cases.
Q: “Cool. What is the pattern?” A: (I’m not sure yet)
I ran into similar things when I was asking about functions like “chunked()” that were available to Lists but not Arrays. It is fine if the answer is “not many people have mentioned it, so don’t worry about it.”