0

Well this question may have been asked before but I could not find an exact match so I will give it a try.

I want to cast a float[] to a byte[] in way a single float would be cast (with loss of information etc), meaning I want to keep only the last 8bits of each float in the array. I found some code involving ByteBuffer, but this approach converted all 32bit of each float to 4 bytes (of 8 bits each) which is not the desired output (if someone is interested though, the link is http://www.javalobby.org/java/forums/t18962.html)

I did not find any code for this casting so I just used a classic for loop:

public static byte[] float2ByteArray(float floatArray[]) {
    byte[] byteArray = new byte[floatArray.length]; 
    for(int i = 0; i < floatArray.length; i++) {
        byteArray[i] = (byte) floatArray[i];
    }
    return byteArray;
} 

My question is if there is a more efficient way to achieve the same result that I am not aware of?

9
  • Are you having performance problems with this particular loop? Commented May 22, 2014 at 12:46
  • 6
    >"in way a single float would be casted (with loss of information etc) meaning I want to keep only the last 8bits of each float in the array." This is not how the float -> byte conversion works in Java. Commented May 22, 2014 at 12:47
  • how long is your array? Commented May 22, 2014 at 12:48
  • Are you by any chance hoping to cast floats in some range to the full range of byte values? Commented May 22, 2014 at 12:55
  • 2
    It's not the way float -> byte conversion works in any language. The last 8 bits of a single precision IEEE-754 number is the LSB of the mantissa, so is absolutely useless, as any meaningful numerical expression relating to the original number. If what you want to do is instead truncate the value, you will need an algorithm for that, Which among other things, determines what happens to numbers that are too large, or too small to fit in a byte. Commented May 22, 2014 at 13:09

1 Answer 1

1

Your general approach with the loop is the way to go. One may tinker with the loop structure (unrolling etc.) to gain a few percent better performance, but thats generally something you only want to bother with at the very end of functional development (if at all).

Whats more of a problem here is that you do not check if your floats fit into a byte. Due to java's (somewhat peculiar) semantics for operations with data types smaller than int, the cast:

byte b = (byte) floatValue;

Can result in very ugly surprises when the float value exceeds the range of a byte. Because implicitly this conversion works as follows:

int i = (int) floatValue;
byte b = (byte) i;

And that is not what you will intuitively expect. If floatValue fits into an int, but not a byte, your final byte value will be the truncated int value. So for example:

float f = 256F;
byte b = (byte) f;

Results in a byte value of 0 (zero), not 127 as one would ordinarily expect. Be wary of that and round/clip your float value accordingly before casting.

As far as performance goes, float -> int/byte cast is by far the most costly operation here (per element).

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the analysis. I really don't have an issue about the float fitting into the byte because it's just rgb values casted to float for arithmetic reasons. The whole idea is to make this conversion in memory than reading again the input image file, which I guess it's costlier, isn't?
@Eypros If the cast semantics aren't a problem in your use case your code should do just fine. I wouldn't worry about the performance of this conversion too much, most likely whatever else your program does will take much more time, so spending a lot of brain power here will yield little return in terms of performance.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.