Thread: Bit shifting with float variables

  1. #1
    Registered User
    Join Date
    May 2005
    Location
    Toronto, Canada
    Posts
    257

    Bit shifting with float variables

    I have to shift bits in a float variable, but it is an illegal operation apperantly. So, I tried to read i nthe binary number into a long int variable, do all the shifting and it works. The problem is that when I try to print the value stored in the long variable it is treated as an int, assigning that value to the float and then printing doesn't work either. Is there another way to either read in the value from the long int into the float without variable type converstion or to bit shift in a float?

    Thanks

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    If you really want to bit-shift a float, you could use a method called fixed-point. Say you want to hold the number 1.23 (and bit-shift it later). You would store 123 in an int, and every time you accessed the variable you would divide the value by 100:

    Code:
    int i = 123;
    i = i << 3;
    printf("%f", i/100.0);
    I hope this helps.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    What would you expect from say

    2.0 << 1
    (assuming that it worked)

    Sure you can cast to an int, shift the bits, cast it back to a float and get "an answer", but unless you know what you're doing, it's unlikely to be the answer you want.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    May 2005
    Location
    Toronto, Canada
    Posts
    257
    I am trying to interpret a binary file and unless I put the bits in the rught position and read it as a float, the numbers mean nothing. I know what order they should go in but I don't know what eah number is, so dividing by anything won't work.
    Her's the code I have so far, but the convertion from tempValue to Value doesn't work at all. It spits out an incorrect int, loosing all the decimal places.

    Thanks for the replies so far.
    Code:
    # include <stdio.h>
    # define BYTE21 0X0000ffff
    # define BYTE43 0Xffff0000
    
    int
    main (void)
    {
    	FILE *inp; 
    	
    	
        float Value; 
        long TempValue;
        long new21, new43;
    
    	inp = fopen("test_outp.baf", "rb");
    
    	if(!inp)
    		printf("The file could not be opened.\n");
    
    	fseek(inp, sizeof(char)*3116,SEEK_SET); 
    
    
    	fread(&TempValue,sizeof(long),1,inp);
    
    	new21 = (TempValue & BYTE21) << 16;
    	new43 = (TempValue & BYTE43) >> 16;
    
    	TempValue = new21 | new43;
    
    	Value = TempValue;
    		
    	printf("%f \n", Value);  
    
        return (0);
    
    }

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You can't use bitwise operations on floating point numbers. Why must you use a float again? You were a bit vague.

    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    Registered User
    Join Date
    May 2005
    Location
    Toronto, Canada
    Posts
    257
    Quote Originally Posted by quzah
    You can't use bitwise operations on floating point numbers. Why must you use a float again? You were a bit vague.

    Quzah.
    I have to read in real numbers. If for say the 4 bytes I'm reading contain 5.25 only a float will read them properly, other variables, ex. int , wil read the binary 5.25 as 1034147594, becasue they don't know that the last 23 bits are the decimal part of the number. And I have to bit-shift. Fun, I know.

  7. #7
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Avoid using signed values for bit shifting.

    Do you have a short example input file that demonstrates the problem and your expected result?
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    I still don't understand what you're really trying to do. You have a file that contains what? Is it a text file, binary? How was this file created? Writing a simple floating point number, in binary mode, to a file, or what?
    Code:
    fwrite( &myfloaty, sizeof( myfloaty ), 1, fp );
    If you're doing this, why don't you just use something like fread to read it back in? It would help if you actually provided a sample, or really clear description of your expected input / output.

    Quzah.
    Hope is the first step on the road to disappointment.

  9. #9
    Registered User
    Join Date
    May 2005
    Location
    Toronto, Canada
    Posts
    257
    Say the value in the file is a3 3d 0a d7. To interpret correctly it should be read as 3d a3 d7 0a. If I scan in directly from file it means nothing. If I read it into a long int then bit-shift, put the bytes in the right order. if I fprint the in value it prints as 1034147594, if I assign the value in the int to a float variable it prints as 1034147594.0000000.
    I tried scanning in a random real number into the float and hten printing it, it works, but without bit-shifting.

  10. #10
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    After the bit-shifting of the integer, get a float value by casting the integer's address to a float* and dereferencing it.
    Code:
    #include <stdio.h>
    
    int main (void)
    {
       float value;
       unsigned long temp = 0xD70A3DA3; /* endianness */
       printf("temp = %08X\n", temp);
       temp = ((temp & 0xFFFF) << 16) | ((temp & 0xFFFF0000) >> 16);
       printf("temp = %08X\n", temp);
       value = *(float*)&temp;
       printf("value = %g\n", value);
       return 0;
    }
    
    /* my output
    temp = D70A3DA3
    temp = 3DA3D70A
    value = 0.08
    */
    Last edited by Dave_Sinkula; 05-24-2005 at 12:22 PM. Reason: Added code.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  11. #11
    Registered User
    Join Date
    May 2005
    Location
    Toronto, Canada
    Posts
    257
    Quote Originally Posted by Dave_Sinkula
    After the bit-shifting of the integer, get a float value by casting the integer's address to a float* and dereferencing it.
    Code:
    #include <stdio.h>
    
    int main (void)
    {
       float value;
       unsigned long temp = 0xD70A3DA3; /* endianness */
       printf("temp = %08X\n", temp);
       temp = ((temp & 0xFFFF) << 16) | ((temp & 0xFFFF0000) >> 16);
       printf("temp = %08X\n", temp);
       value = *(float*)&temp;
       printf("value = %g\n", value);
       return 0;
    }
    
    /* my output
    temp = D70A3DA3
    temp = 3DA3D70A
    value = 0.08
    */

    It works like magic. I tried that before but I couldn't figure out how to cast and what to cast it to properly.
    I actually wrote another function to swap the bytes in the float. A pointer to the float is passed to it and it swaps the bytes using poiter addresses and returns a revered float.

    thanks a lot though,

    A.

  12. #12
    Registered User kryptkat's Avatar
    Join Date
    Dec 2002
    Posts
    638
    Why would this not work?

    value = (float*)&temp;

    edit
    assumed you

    float *value;

    output


    C:\borland\bcc55\bin>testfloatpoint0001
    temp = D70A3DA3
    temp = 3DA3D70A
    value = 9.02219e-12

    C:\borland\bcc55\bin>
    Last edited by kryptkat; 05-24-2005 at 03:17 PM.

  13. #13
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by kryptkat
    Why would this not work?
    ::shrugs::
    Code:
    #include <stdio.h>
    
    int main (void)
    {
       float *value;
       unsigned long temp = 0xD70A3DA3; /* endianness */
       printf("temp = %08X\n", temp);
       temp = ((temp & 0xFFFF) << 16) | ((temp & 0xFFFF0000) >> 16);
       printf("temp = %08X\n", temp);
       value = (float*)&temp;
       printf("*value = %g\n", *value);
       return 0;
    }
    
    /* my output
    temp = D70A3DA3
    temp = 3DA3D70A
    *value = 0.08
    */
    [edit]At some point I should probably add a disclaimer about sizes of int and float and portability and stuff.
    Last edited by Dave_Sinkula; 05-24-2005 at 03:22 PM.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  14. #14
    Registered User kryptkat's Avatar
    Join Date
    Dec 2002
    Posts
    638
    oh ok. i should have realized that.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Opengl walking leg animation
    By Bobby230 in forum C Programming
    Replies: 3
    Last Post: 03-05-2006, 03:41 PM
  2. Backdooring Instantaneous Radius of Curvature & Functions
    By just2peachy in forum C++ Programming
    Replies: 8
    Last Post: 10-06-2004, 12:25 PM
  3. Display list not displaying?
    By psychopath in forum Game Programming
    Replies: 5
    Last Post: 09-19-2004, 06:47 PM
  4. error declaration terminated incorrectly help
    By belfour in forum C++ Programming
    Replies: 7
    Last Post: 11-25-2002, 09:07 PM
  5. How do you search & sort an array?
    By sketchit in forum C Programming
    Replies: 30
    Last Post: 11-03-2001, 05:26 PM