Help converting VB code to C#

Associate
Joined
18 Oct 2002
Posts
2,092
Location
Edinburgh
Right, so i have a piece of code which converts an IEEE float (Number) in vb to a different representation of exponent and mantissa.

Im having great difficulty converting this to C# due to the way the code deals with bit masking of whole byte arrays. Anyone able to help?

Code:
      If (Number And &H80000000) = &H80000000 Then
         'negative
         'mask off the sign bit
         Number = (Number And &H7FFFFFFF)
         Mantissa = &HC000& - ((Number And &H7FFFFF) \ (2 ^ 9))
      Else
         Mantissa = &H4000& + ((Number And &H7FFFFF) \ (2 ^ 9))
      End If 
      'positive
      If Number = 0 Then
         ' zero is represented as Mantissa 0 and Exponent 128
         Mantissa = 0: Exponent = &H80& 
      Else 
         Exponent = (((Number \ (2 ^ 23)) - 126&) And &HFF&)
      End If
 
Associate
Joined
14 May 2010
Posts
1,136
Location
Somerset
How about this...

Code:
        long number = 0x80000000;
        long mantissa;
        long exponent;

        if ((number & 0x80000000) == 0x80000000)
        {
            //negative
            //mask off the sign bit
            number = (number & 0x7FFFFFFF);
            mantissa = 0xC000 - ((number & 0x7FFFFF) / (2 ^ 9));
        }
        else
        {
            mantissa = 0x4000 + ((number & 0x7FFFFF) / (2 ^ 9));
        }
        //positive
        if (number == 0)
        {
            // zero is represented as Mantissa 0 and Exponent 128
            mantissa = 0;
            exponent = 0x80;
        }
        else
        {
            exponent = (((number / (2 ^ 23)) - 126) & 0xFF);
        }
 
Associate
OP
Joined
18 Oct 2002
Posts
2,092
Location
Edinburgh
That looks good except if i use a number say 555.55

the VB gives back mantissa 16385 and exponent 130
the code above gives back mantissa 16434 and exponent 156
 
Associate
OP
Joined
18 Oct 2002
Posts
2,092
Location
Edinburgh
ok so the whole point in the code is to convert a float to a mantissa and exponent

the code you did is good, but it only accepts a long (int) i need to do the same but to the float.

I think i have it, the numbers are not exact but i think thats due to the extra precission

Code:
        public void Marshall(float number)
        {
            long mantissa;
            long exponent;

            if (((byte)number & 0x80000000) == 0x80000000)
            {
                //negative
                //mask off the sign bit
                number = ((byte)number & 0x7FFFFFFF);
                mantissa = 0xC000 - (((byte)number & 0x7FFFFF) / (2 ^ 8));
            }
            else
            {
                mantissa = 0x4000 + (((byte)number & 0x7FFFFF) / (2 ^ 8));
            }
            //positive
            if (number == 0)
            {
                // zero is represented as Mantissa 0 and Exponent 128
                mantissa = 0;
                exponent = 0x80;
            }
            else
            {
                exponent = ((((byte)number / (2 ^ 22)) - 126) & 0xFF);
            }
            MessageBox.Show(mantissa + ":" + exponent);
        }


Anyone fancy helping reverse it?? :O
 
Last edited:
Associate
Joined
11 Nov 2003
Posts
1,696
Location
South Yorkshire
I'd say there are a few issues here. First, you need to get the underlying representation of the float. Simply casting to a uint or long won't do the job. BitConverter will help there.

Second, the ^ operator in C# is not power, it's XOR. It's useful to know that dividing x by (2 ^ n) is equivalent to right-shifting an unsigned number n bits (i.e. x >> n). So you would end up with something like:

Code:
        public Tuple<uint, uint> Marshall(float number)
        {
            uint exponent, mantissa;

            // First, convert from underlying representation
            var rep = BitConverter.ToUInt32(BitConverter.GetBytes(number), 0);
            if ((rep & 0x80000000) == 0x80000000)
            {
                rep &= ~0x80000000;
                mantissa = 0xC000 - ((rep & 0x7FFFFF) >> 9);
            }
            else
            {
                mantissa = 0x4000 + ((rep & 0x7FFFFF) >> 9);
            }

            if (rep == 0)
            {
                mantissa = 0;
                exponent = 0x80;
            }
            else
            {
                exponent = (((rep >> 23) - 126) & 0xFF);
            }

            return new Tuple<uint, uint>(exponent, mantissa);
        }

To use:

Code:
var result = Test.Marshall(1.234f);
// exponent is result.Item1
// mantissa is result.Item2

It builds, but I don't know if it gives the "correct" answer. For the 555.55 case it returns (10, 17777).
 
Associate
OP
Joined
18 Oct 2002
Posts
2,092
Location
Edinburgh
Sorry for the late reply, you sir are a legend.

Thanks for that i forgot about ^ in C#

I finally nailed it, both ways thanks to your code:

Code:
        //Floating Point from a Mantissa and Exponent
        public Single MarshallReverse(int Mant, int Exp)
        {
            long k;
            long m;
            long j;
            

            k = Mant;
            m = Exp;

            //Std representation of zero is mantissa 0 and exponent 128
            if (k == 0x0 && m == 0x80){ j = 0x0;}
            else if ((k & 0x8000) == 0x8000)
            {
                //its negative so mask off the negative bit
                j = ((0x10000 - k) & 0x3fff) << 9;
                j = j | 0x80000000 | (((m + 126) & 0xff) << 23);
            }
            else
            {
                j = (k & 0x3fff) << 9;
                j = j | (((m + 126) & 0xff) << 23);
            }
            byte[] ba = BitConverter.GetBytes(j);
            Single ans = BitConverter.ToSingle(ba, 0);
            return ans;
        }

        //Procedure to create a mantissa and exponent from a float
        public void Marshall(float number)
        {
            uint exponent, mantissa;

            // First, convert from underlying representation
            var rep = BitConverter.ToUInt32(BitConverter.GetBytes(number), 0);
            // If its negative
            if ((rep & 0x80000000) == 0x80000000)
            {
                rep &= ~0x80000000;
                //Subtract the sign and exponent and shift back 9 bits
                mantissa = 0xC000 - ((rep & 0x7FFFFF) >> 9);
            }
            else
            {
                //Subtract the exponent and shift back 9 bits
                mantissa = 0x4000 + ((rep & 0x7FFFFF) >> 9);
            }

            if (rep == 0)
            {
                //Std Representation of 0 is mantissa 0 exponent 128
                mantissa = 0;
                exponent = 0x80;
            }
            else
            {
                //Exponent is shifted 23 bits which clears them
                exponent = (((rep >> 23) - 126) & 0xFF);
            }

            textBox9.Text = mantissa.ToString();
            textBox10.Text = exponent.ToString();
        }
 
Back
Top Bottom