binary conversion

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • bimbam
    New Member
    • Aug 2007
    • 19

    binary conversion

    Hi,

    I wish to compare 2 black and white images of about 4000 pixels. So I have 2 arrays of 4000 integers int of value 0 or 1. My idea was to convert each array to a single binary number built by putting all the integers one after the other. I could then convert this number to a base 10 number. I would use this number as a signature of each image to compare them.

    The problem is the amount of operations to make to build the binary number. Multiplying each 4000 number by a power of 10 and summing everything is longer than comparing directly each frame pixel by pixel. (As I have a lot of images, I think it's worth doing it anyway).

    So would you have a method you think would be faster to build the binary number? In fact, it might be possible to use only the last bit of the pixel value integer and store it directly in 4000 bit zone. But I don't know how to do that.

    Regards
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    Are you using C++??

    If so, use a bitset rather than integers:
    [code=cpp]
    bitset<4000> array1;
    bitset<4000> array2;

    if(array1 == array2)
    {
    cout << "Bits are equal" <<endl;
    }
    [/code]

    This way you use 8000 bits instead of 8000 integers.

    Comment

    • bimbam
      New Member
      • Aug 2007
      • 19

      #3
      Originally posted by weaknessforcats
      Are you using C++??

      If so, use a bitset rather than integers:
      [code=cpp]
      bitset<4000> array1;
      bitset<4000> array2;

      if(array1 == array2)
      {
      cout << "Bits are equal" <<endl;
      }
      [/code]

      This way you use 8000 bits instead of 8000 integers.

      Thank you for the tip.

      I don't use C++ but there might be a function in C to do the same?

      Regards

      Comment

      • weaknessforcats
        Recognized Expert Expert
        • Mar 2007
        • 9214

        #4
        You write the function in C++ and compile it as extern "C":

        [code=cpp]
        extern "C" int CompareBits(bit set<4000>& array1, bitset<4000>arr ay2)
        {

        if (array1 == array2) return 1; //true
        return false;
        }
        [/code]

        Usually you can have a mixture of C and C++ files in the same IDE project. Visual Studio compiles are .c files using rules of C and all .cpp files using rules of C++.

        The extern "C" is a command to the compiler to not alter the name of the function. That way the name remains as CompareBits. Otherwise, the compiler will has the name and the arguments into a unique string. It's how C++ handles multiple functions with the same name.

        Comment

        • weaknessforcats
          Recognized Expert Expert
          • Mar 2007
          • 9214

          #5
          Oops. No bitsets in C for the function arguments.

          Let me post again in a minute.

          Comment

          • weaknessforcats
            Recognized Expert Expert
            • Mar 2007
            • 9214

            #6
            OK. Let;s try this again.

            Here is possible C code:
            [code=c]
            #include <stdio.h>


            #define FALSE 0
            #define TRUE !FALSE

            void* CreateBitArray( );
            int CompareBitArray (void* array1, void* array2);

            int main()
            {
            void* array1 = CreateBitArray( );
            void* array2 = CreateBitArray( );

            if(CompareBitAr ray(array1, array2) == TRUE)
            {
            printf("Bits are equal\n");
            }
            }
            [/code]

            Here the 4000 bit bitsets are created by a C++ function that returns a pointer to the bits.

            Then the bitsets are compared by a C++ function that returns a TRUE/FALSE.

            This would be in a .c file.

            The C++ code might be:
            [code=cpp]
            #include <bitset>
            using namespace std;

            extern "C"
            void* CreateBitArray( )
            {
            bitset<4000>* b = new bitset<4000>;
            return reinterpret_cas t<void*> (b);
            }

            extern "C" int CompareBitArray (void* array1, void* array2)
            {
            bitset<4000>* a1 = reinterpret_cas t<bitset<4000>* > (array1);
            bitset<4000>* a2 = reinterpret_cas t<bitset<4000>* > (array2);
            if (a1 == a2) return 1; //true
            return 0; //false
            }
            [/code]

            The C++ code is an a .cpp file.

            Essentially, you would write wrappers in C++ that could be called fromn C. These wrappers would allow you to use any bitset methods you wanted.

            Comment

            • bimbam
              New Member
              • Aug 2007
              • 19

              #7
              Originally posted by weaknessforcats
              OK. Let;s try this again.

              Here is possible C code:
              [code=c]
              #include <stdio.h>


              #define FALSE 0
              #define TRUE !FALSE

              void* CreateBitArray( );
              int CompareBitArray (void* array1, void* array2);

              int main()
              {
              void* array1 = CreateBitArray( );
              void* array2 = CreateBitArray( );

              if(CompareBitAr ray(array1, array2) == TRUE)
              {
              printf("Bits are equal\n");
              }
              }
              [/code]

              Here the 4000 bit bitsets are created by a C++ function that returns a pointer to the bits.

              Then the bitsets are compared by a C++ function that returns a TRUE/FALSE.

              This would be in a .c file.

              The C++ code might be:
              [code=cpp]
              #include <bitset>
              using namespace std;

              extern "C"
              void* CreateBitArray( )
              {
              bitset<4000>* b = new bitset<4000>;
              return reinterpret_cas t<void*> (b);
              }

              extern "C" int CompareBitArray (void* array1, void* array2)
              {
              bitset<4000>* a1 = reinterpret_cas t<bitset<4000>* > (array1);
              bitset<4000>* a2 = reinterpret_cas t<bitset<4000>* > (array2);
              if (a1 == a2) return 1; //true
              return 0; //false
              }
              [/code]

              The C++ code is an a .cpp file.

              Essentially, you would write wrappers in C++ that could be called fromn C. These wrappers would allow you to use any bitset methods you wanted.
              Thanks,

              I'll try that.

              Regards

              Comment

              • bimbam
                New Member
                • Aug 2007
                • 19

                #8
                How do you link the 2 files together?

                Regards

                Comment

                • weaknessforcats
                  Recognized Expert Expert
                  • Mar 2007
                  • 9214

                  #9
                  If you are using an IDE like Visual Studio, you add both files to the same project and build. Visual Studio compiles all files with .c extensions as C code and all files with .cpp extensions as C++ code. Therefore, any project can be a mixture of C and C++ code.

                  If you are writing your own makefile, then use a C compiler on the .c file and a C++ compiler on the .cpp file. Route both object files to the linker.

                  Comment

                  • bimbam
                    New Member
                    • Aug 2007
                    • 19

                    #10
                    Originally posted by weaknessforcats
                    If you are using an IDE like Visual Studio, you add both files to the same project and build. Visual Studio compiles all files with .c extensions as C code and all files with .cpp extensions as C++ code. Therefore, any project can be a mixture of C and C++ code.

                    If you are writing your own makefile, then use a C compiler on the .c file and a C++ compiler on the .cpp file. Route both object files to the linker.
                    Hi,

                    I tried to compile the examples you sent me. I try to use a Makefile but I'm not too familiar with it. Could you give me a help? Do I need a header file?

                    I called the 2 files you sent me main.c and test.cpp. Here is my makefile:
                    Code:
                    CC=gcc
                    CPP=g++
                    CFLAGS=-W -Wall -ansi -pedantic
                    CXXFLAGS=-W -Wall -ansi -pedantic
                    LDFLAGS=
                    EXEC=test
                    
                    all: $(EXEC)
                    
                    test: test.o main.c
                            $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
                    
                    test.o: test.cpp
                            $(CPP) -o $@ $< $(CXXFLAGS)
                    The errors are:

                    gcc -o test test.o main.c -W -Wall -ansi -pedantic
                    main.c: In function ‘main’:
                    main.c:18: warning: control reaches end of non-void function
                    test.o: In function `CreateBitArray ':
                    test.cpp:(.text +0x3f): undefined reference to `operator new(unsigned int)'
                    test.o:(.eh_fra me+0x11): undefined reference to `__gxx_personal ity_v0'
                    collect2: ld returned 1 exit status
                    make: *** [test] Error 1


                    Regards

                    Comment

                    • weaknessforcats
                      Recognized Expert Expert
                      • Mar 2007
                      • 9214

                      #11
                      I can't do makefiles much myself since I rely on the IDE - and it's Windows to boot so the make files are in different formats and are read differently.

                      Perhaps a gcc/g++ person here can help you. JosAH usually has answers for stuff like this.

                      Comment

                      • bimbam
                        New Member
                        • Aug 2007
                        • 19

                        #12
                        OK.

                        So JosAH (or anyone) can you help me?

                        Regards.

                        Comment

                        • JosAH
                          Recognized Expert MVP
                          • Mar 2007
                          • 11453

                          #13
                          Originally posted by bimbam
                          Hi,

                          I tried to compile the examples you sent me. I try to use a Makefile but I'm not too familiar with it. Could you give me a help? Do I need a header file?

                          I called the 2 files you sent me main.c and test.cpp. Here is my makefile:
                          Code:
                          CC=gcc
                          CPP=g++
                          CFLAGS=-W -Wall -ansi -pedantic
                          CXXFLAGS=-W -Wall -ansi -pedantic
                          LDFLAGS=
                          EXEC=test
                          
                          all: $(EXEC)
                          
                          test: test.o main.c
                                  $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
                          
                          test.o: test.cpp
                                  $(CPP) -o $@ $< $(CXXFLAGS)
                          The errors are:

                          gcc -o test test.o main.c -W -Wall -ansi -pedantic
                          main.c: In function ‘main’:
                          main.c:18: warning: control reaches end of non-void function
                          test.o: In function `CreateBitArray ':
                          test.cpp:(.text +0x3f): undefined reference to `operator new(unsigned int)'
                          test.o:(.eh_fra me+0x11): undefined reference to `__gxx_personal ity_v0'
                          collect2: ld returned 1 exit status
                          make: *** [test] Error 1


                          Regards
                          Well, you've got one warning: main() doesn't return anything and C doesn't like
                          that but even worse you have a link (collect) error because you're linking a
                          piece of C++ code as if it were plain C. The undefined reference to __gxx_etc.
                          thing is just an artifact because of that.

                          My suggestion is to go the whole nine yards either for C++ or C, but not both
                          of them. A bitset is just an array of (unsigned) ints or chars as far as C is
                          concerned. A simple memcmp() can compare those. Or you use C++ where
                          you can express the same more elegantly.

                          kind regards,

                          Jos

                          Comment

                          Working...