This discussion is archived
12 Replies Latest reply: Jul 22, 2008 3:17 PM by 807589 RSS

Floating point number to IBM bytes

807589 Newbie
Currently Being Moderated
Hello,

I'm trying to convert a float value to a byte array (but in IBM standard).

I understand that the general idea will be the following algorithm:

1. process the sign, exponent and fraction from the float value (using IBM standard)
2. build the bytes from the S, E, F from step 1.

So far, I only have the step 2 like this:

public static byte[] toBytesIbm( int signBit, int exponent, long fraction ) {
byte[] bytes = new byte[4];
bytes[0] = (byte)(signBit + exponent);
bytes[1] = (byte)((fraction & 0x00FF0000) >> 16);
bytes[2] = (byte)((fraction & 0x0000FF00) >> 8);
bytes[3] = (byte)(fraction & 0x000000FF);
return bytes;
}

Getting the sing bit is also not a problem, so the real work is in getting the exponent and fraction from the number. I don't know how to do this. I have code from a trusted source to convert from IBM bytes to IEEE float numbers, so I can check if the bytes are correct.

Can anyone help me with this?

Thanks in advance

  • 1. Re: Floating point number to IBM bytes
    807589 Newbie
    Currently Being Moderated
    develop.daniel wrote:
    bytes[0] = (byte)(signBit + exponent);
    This line just plain looks wrong.

    The bit-masking in your code is not needed.

    You haven't specified an endian-ness.

    You haven't specified what the format is.
  • 2. Re: Floating point number to IBM bytes
    807589 Newbie
    Currently Being Moderated
    I'm guessing its this format: [http://en.wikipedia.org/wiki/IBM_Floating_Point_Architecture]
  • 3. Re: Floating point number to IBM bytes
    807589 Newbie
    Currently Being Moderated
    newark wrote:
    I'm guessing its this format: [http://en.wikipedia.org/wiki/IBM_Floating_Point_Architecture]
    Interesting; that first line is wrong then, unless sign has already been pre-shifted into place.
  • 4. Re: Floating point number to IBM bytes
    807589 Newbie
    Currently Being Moderated
    public static byte[] toBytesIbm( int signBit, int exponent, long fraction ) {
    byte[] bytes = new byte[4];
    bytes[0] = (byte)(signBit + exponent);
    bytes[1] = (byte)((fraction & 0x00FF0000) >> 16);
    bytes[2] = (byte)((fraction & 0x0000FF00) >> 8);
    bytes[3] = (byte)(fraction & 0x000000FF);
    return bytes;
    }
    public static byte[] toBytesIBM( int signBit, int exponent, long fraction ) {
          byte[] bytes = new byte[4];
          bytes[0] = (byte)( fraction & 0x000000FF )
          bytes[1] = (byte)( ( fraction >> 8 ) & 0x000000FF )
          bytes[2] = (byte)( ( fraction >> 16 ) & 0x000000FF )
          bytes[3] = (byte)( exponent & 0x000000EF );
          bytes[3] |= (byte)( (signBit << 7) & 0x00000080 );
          return bytes;
    }
    I think I'd code it something similar to this if that's the format to use.
  • 5. Re: Floating point number to IBM bytes
    807589 Newbie
    Currently Being Moderated
    Brushfire wrote:
    public static byte[] toBytesIBM( int signBit, int exponent, long fraction ) {
    byte[] bytes = new byte[4];
    bytes[0] = (byte)( fraction & 0x000000FF )
    bytes[1] = (byte)( ( fraction >> 8 ) & 0x000000FF )
    bytes[2] = (byte)( ( fraction >> 16 ) & 0x000000FF )
    bytes[3] = (byte)( exponent & 0x000000EF );
    bytes[3] |= (byte)( (signBit << 7) & 0x00000080 );
    return bytes;
    }
    The masks for fraction and signBit are not needed due to the cast to byte. The mask you use on the exponent is incorrect (should be 0x7F).

    It also assumes the little-endian byte order.
  • 6. Re: Floating point number to IBM bytes
    807589 Newbie
    Currently Being Moderated
    Thanks for the correct. I'm never quite sure about the masks, but I've had issues with extra data being introduced before, so I like it better safe than sorry.

    All the stuff I currently do with bytes assumes that bit 0 starts with byte 0 bit 0. But failing that I'd flip it :)
  • 7. Re: Floating point number to IBM bytes
    807589 Newbie
    Currently Being Moderated
    Brushfire wrote:
    Thanks for the correct. I'm never quite sure about the masks, but I've had issues with extra data being introduced before, so I like it better safe than sorry.
    The mask is needed when a narrower primitive has been sign-extended to a wider primitive, and you want to keep the result unsigned.

    But in this case, the result is then cast to byte, which removes all the upper bits that the mask was trying to set to zero in the first place.

    If you need to store a byte in an int without sign-extension, you need a mask:
    int n = someByte & 0xFF;
    If you want to store the lower 8 bits of an int in another int, you need a mask:
    int lowerEight = someInt & 0xFF;
    But if you want to store the lower 8 bits in a byte, just cast:
    byte lowerEight = (byte)someInt;
  • 8. Re: Floating point number to IBM bytes
    807589 Newbie
    Currently Being Moderated
    I'm sorry, I failed to mention it... Yes this is the standard to be used (http://en.wikipedia.org/wiki/IBM_Floating_Point_Architecture).

    Also, I want to thank every one of you. You've all been very helpful. I've actually finished the code, and with the modifications you've suggested, it works fine. I'll still need to perform additional tests, but it should be alright.

    Best Regards

    Edited by: develop.daniel on Jul 22, 2008 2:46 PM
  • 9. Re: Floating point number to IBM bytes
    807589 Newbie
    Currently Being Moderated
    Here's what you need to do: Look at the page on [IBM Floating Point Architecture|http://en.wikipedia.org/wiki/IBM_Floating_Point_Architecture] and compare it to the page on [single-precision IEEE 754|http://en.wikipedia.org/wiki/IEEE_754].

    Use Float.floatToIntBits() to get the raw bits. Using what you've learned from those pages, come up with an algorithm (or find one) to convert between the formats.

    EDIT: nevermind, see you got it.

    Edited by: paul.miner on Jul 22, 2008 4:54 PM
  • 10. Re: Floating point number to IBM bytes
    807589 Newbie
    Currently Being Moderated
    Ups, I think I just gave the "correct" answer to the wrong person. I'm sorry, I'm new in this forum thing.

    Anyways, my special thanks to paul.miner and brushfire for their contribution and clarifications.

    In case you are interested, I got the conversion algorithm (or more precisely C code) from:
    [http://www.codeproject.com/KB/applications/libnumber.aspx?fid=236108&df=90&mpp=25&noise=3&sort=Position&view=Quick&select=2646605&fr=1]
  • 11. Re: Floating point number to IBM bytes
    807589 Newbie
    Currently Being Moderated
    Thanks to all for your contributions
  • 12. Re: Floating point number to IBM bytes
    807589 Newbie
    Currently Being Moderated
    I'm just going to post my corrected code based on Paul's suggestions in case some one uses this as a reference
    public static byte[] toBytesIBM( int signBit, int exponent, long fraction ) {
          byte[] bytes = new byte[4];
          bytes[0] = (byte) fraction; 
          bytes[1] = (byte) ( fraction >> 8 ) ;
          bytes[2] = (byte) ( fraction >> 16 );
          bytes[3] = (byte) ( exponent & 0x0000007F );
          bytes[3] |= (byte) ( signBit << 7 );
          return bytes;
    }