Bashalex Bashalex - 1 year ago 55
Java Question

Conversion from float to char[] in Java (Android)

I have an application where in onDraw() method of View I need to draw a couple of float numbers on the screen.
In order to avoiding garbage collection I'm trying to get rid of all allocations in this method. The problem is that I want to draw floats on the screen with specified number of decimals and I can't find any information how to do it without String.format() and without using Strings at all. Even simple conversion from float to char[] seems to be a problem without Strings and allocation of memory.

So the question is how to manage this issue?

P.S. There is no way to convert them in advance before onDraw() method because numbers can be changed during user touch events (e.g. scrolling).

Answer Source

Implement your own formatter. Below is an example of a simplified formatter.

It fills the buffer from the end and returns the starting index. It will fail with ArrayIndexOutOfBoundsException if float is too big for the buffer, and it won't handle negative values, infinity and NaN. I'll leave that up to you.

If you need buffer filled from beginning, just use System.arraycopy() to move the characters.

As you can see, the only allocation is the char buffer.

public static int format(char[] buffer, float value, int decimals) {
    float v = value;
    for (int i = 0; i < decimals; i++)
        v *= 10f;
    int num = Math.round(v);
    int idx = buffer.length;
    for (int i = 0; i < decimals; i++, num /= 10)
        buffer[--idx] = (char) ('0' + num % 10);
    if (decimals > 0)
        buffer[--idx] = '.';
    do {
        buffer[--idx] = (char) ('0' + num % 10);
    } while ((num /= 10) != 0);
    return idx;


char[] buffer = new char[10];
int startIdx = format(buffer, (float)Math.PI, 4);
for (int i = startIdx; i < buffer.length; i++)