Splitting a numbers binary representation for a double.

 
Thread Tools Search this Thread
Homework and Emergencies Homework & Coursework Questions Splitting a numbers binary representation for a double.
# 1  
Old 06-30-2012
Splitting a numbers binary representation for a double.

Use and complete the template provided. The entire template must be completed. If you don't, your post may be deleted!

1. The problem statement, all variables and given/known data:
Split a 64bit hexadecimal number into two 32 bit numbers or keys.


2. Relevant commands, code, scripts, algorithms:
Code:
double key = 0; //Stores the key value entered by the user.
double key_copy = key;
int k1;  //1st half of key.
int k2;  //2nd half of key.

3. The attempts at a solution (include all code and scripts):
Code:
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;

int main( int argc, char * argv[] )
{
double key = 0; //Stores the key value entered by the user.
double index = 15; /*Used for pow function.  For loop index corresponds to
hexadecimal powers.*/
if( argc > 1 )
{
if( strlen( argv[1] ) == 16 )
{
        for( int i = 0; i < 16; i++ )
        {
                switch( argv[1][i] )
                {
                        case '0': key += 0 * pow( 16.0, index );
                                break;
                        case '1': key += 1 * pow( 16.0, index );
                                break;
                        case '2': key += 2 * pow( 16.0, index );
                                break;
                        case '3': key += 3 * pow( 16.0, index );
                                break;
                        case '4': key += 4 * pow( 16.0, index );
                                break;
                        case '5': key += 5 * pow( 16.0, index );
                                break;
                        case '6': key += 6 * pow( 16.0, index );
                                break;
                        case '7': key += 7 * pow( 16.0, index );
                                break;
                        case '8': key += 8 * pow( 16.0, index );
                                break;
                        case '9': key += 9 * pow( 16.0, index );
                                break;
                        case 'A': key += 10 * pow( 16.0, index );
                                break;
                        case 'B': key += 11 * pow( 16.0, index );
                                break;
                        case 'C': key += 12 * pow( 16.0, index );
                                break;
                        case 'D': key += 13 * pow( 16.0, index );
                                break;
                        case 'E': key += 14 * pow( 16.0, index );
                                break;
                        case 'F': key += 15 * pow( 16.0, index );
                                break;
                        default: cout << "You entered a non-hexadecimal value.\n";
                                exit(0);
                }
                index--;
        }

        double key_copy = key;
        int k1;  //1st half of key.
        int k2;  //2nd half of key.
        key_copy /= pow( 2.0, 32.0 );  //Shift key to right to get 1st half of binary.
        k1 = (int) key_copy;
        key_copy = key;
        key_copy *= pow( 2.0, 31.0 );  //Shift key to left then right to get 2nd half
        key_copy /= pow( 2.0, 31.0 );  //of binary representation.
        k2 = key_copy;

        cout << k1 << endl;
        cout << k2 << endl;
}
}
        return 0;
}


4. Complete Name of School (University), City (State), Country, Name of Professor, and Course Number (Link to Course):
University of Missouri Saint Louis, Saint Louis (Missouri), United States, Michael Schulte, 4780 (cs.umsl.edu/~schulte)

Note: Without school/professor/course information, you will be banned if you post here! You must complete the entire template (not just parts of it).
# 2  
Old 06-30-2012
It would be nice to know what you think isn't working, or where you are stuck. Modulo that, from looking at (not trying to build/execute) your code....

Your approach makes a mountain from a mole hill I think; unless you aren't allowed to use strtoll(). If there are no restrictions, then have a look at the strtoll() manual page, and if you need to add error checking to ensure that a non-hex character hasn't been entered, have a peek at the strspn() manual page too.

If there are restrictions, there still isn't the need for the use of the pow() function; simple (unsigned) character based math and shifting are all that are needed. Consider this example:

Code:
   unsigned char *cval = "123";
    int val = 0;
    int i;

    for( i = 0; i < strlen( cval ); i++ )
    {
        val <<= 4;
        val += cval[i] - '0';
    }
    printf( "%x\n", val );

You'll have to handle a-f and A-F which aren't handled here, but this might point you in the direction of an easier way if strtoll() has to be avoided for the assignment.

Using floating point values for this will make things much more difficult; stick with 64 bit integer. I'd also think about bitwise AND and shift operations as a way to split your key.
# 3  
Old 07-01-2012
The long long int knowledge seems like it will be very helpful along with the unsigned math you showed. The strtoll() I am sure is helpful, I am just not too sure yet what to do with it. Thanks.
# 4  
Old 07-01-2012
Quote:
Originally Posted by robin_simple
The strtoll() I am sure is helpful, I am just not too sure yet what to do with it. Thanks.
Use it to replace your loop that builds values from argv[] elements.
Code:
long long val;

val = strtoll( argv[1], NULL, 16 );


Last edited by vbe; 07-02-2012 at 10:22 AM.. Reason: Missing ] on quote tag...
# 5  
Old 07-02-2012
Code:
#include <iostream>
#include <stdlib.h>
using namespace std;

int main()
{
        char *hex_key = "abcdef012345678";
        long long key = strtoll( hex_key, NULL, 16 );

        cout << key << endl;
}

on compilation:
g++ b.cpp
b.cpp: In function ‘int main()’:
b.cpp:7: warning: deprecated conversion from string constant to ‘char*’

output:
./a.out
773738358679819896

Is there anything I can do to get rid of the warning?

Also, the full hex_key is 9abcdef012345678 which is different from what I used in the above code because of the 9 at the beginning. The output of this is 9223372036854775807
which is different from a result shown on a webpage that calculates hexadecimal numbers. All the outputs for the other hex_key values are consistent with the calculating website. Why is this number different?

Also, in your first reply you gave me
Code:
unsigned char *cval = "123";
    int val = 0;
    int i;

    for( i = 0; i < strlen( cval ); i++ )
    {
        val <<= 4;
        val += cval[i] - '0';
    }
    printf( "%x\n", val );

and I am wondering why you subtract '0' and why you shift 4. Is it necessary to shift << by four each time you add a new hex digit?

---------- Post updated at 08:38 PM ---------- Previous update was at 12:56 PM ----------

ok, strtoull() was the function that gets the whole 16 hex digits. the unsigned long long type was what I should have been using.
# 6  
Old 07-02-2012
Glad you figured that out. I was in the process of replying and when I refreshed saw your addition.

The warning must be a C++ thing; I'm a C person, so that construct makes sense to me. Not sure how to get rid of it.

It is not necessary to shift both values


The subtraction in the code is a quick way to convert a digit represented in ASCII to a value. The numbers 0 through 9 have ASCII values 0x30, 0x31... 0x39. If the input value on the command line is "42" argv[x] points to two bytes: 0x34 0x32. To convert the first character (4) into an integer 4, you can subtract the value of the character zero from it (0x34 - 0x30) which yields 4. You would do the same for the values A-F and a-f to convert the ASCII representation of the hex digit to a value.

Yes, it is necessary to shift the value in val by 4 bits each time you add in a digit. Lets assume "123" was entered on the command line. The first time through the loop val is 0 and the shift has no effect. The character '1' is converted to integer and added to val; val becomes 1.

The second time through the loop val is shifted and becomes 0x10. The character '2' is converted to integer and then is added to val which now holds the value 0x12.

Again val is shifted and bcomes 0x120. The '3' is converted and added to val leaving the variable with 0x123.

Think of it as sliding the digits over one nibble to the left to make room for the next value.

Hope that makes some sense.
This User Gave Thanks to agama For This Post:
Login or Register to Ask a Question

Previous Thread | Next Thread

8 More Discussions You Might Find Interesting

1. UNIX for Beginners Questions & Answers

Splitting a file based on negative and positive numbers

I have a file that is pipe delimited and in Column F they have number values, both positive and negative. I need to take the one file I am starting with and split it into two separate files based on negative and positive numbers. What is the command to do so? And then I need to also transfer... (4 Replies)
Discussion started by: cckaiser15
4 Replies

2. Programming

How bit representation of a number can be done in c?

I have an assignment in which a character is the input of which some bits(from a position to certain position) are to be inverted (1's complement) and then the resultant character is to be returned....for example unsigned char x = J from p = 3 to offset n = 5 01001010 inverted to... (1 Reply)
Discussion started by: ezee
1 Replies

3. Shell Programming and Scripting

Convert binary file to csv and then back to the binary format

Hello *nix specialists, Im working for a non profit organisation in Germany to transport DSL over WLAN to people in areas without no DSL. We are using Linksys WRT 54 router with DD-WRT firmware There are at the moment over 180 router running but we have to change some settings next time. So my... (7 Replies)
Discussion started by: digidax
7 Replies

4. Shell Programming and Scripting

Splitting a file based on positive and negative numbers

Dear All, I have to split a tab delimited file in two files based on the presence of a positive or negative in column number 9 , for example file: A 1 5 erg + 6766 0.9889 0.9817 9.01882 erg inside upstream B 1 8 erg2 + 6766 0.9889 0.9817 -9.22 erg2 inside... (3 Replies)
Discussion started by: paolo.kunder
3 Replies

5. Shell Programming and Scripting

Put double quotes around numbers

Hi, consider a file which has data such as "random text",912345,"54","finish" "random text",9991236745,"9954","finish" I want to replace the numbers that don't have double quotes around them with ones that do; so the output should be "random text","912345","54","finish" "random... (4 Replies)
Discussion started by: Storms
4 Replies

6. Shell Programming and Scripting

Splitting file based on line numbers

Hello friends, Is there any way to split file from n to n+6 into 1 file and (n+7) to (n+16) into other file etc. f.e I have source pipe delimated file with 20 lines and i need to split 1-6 in file1 and 7-16 in file2 and 17-20 in file 3 I need to split into fixed number of file like 4 files... (2 Replies)
Discussion started by: Rizzu155
2 Replies

7. Programming

Internal representation of double

I came across a puzzle which I can not explain. The setup is SCO OpenServer 5.7 (32 bit OS) and native SCO compiler. double is 8 bytes long on this system. I am able to populate the double variable with two different sets of values that produces the same double value, please see below: #include... (7 Replies)
Discussion started by: migurus
7 Replies

8. Shell Programming and Scripting

Using binary representation of IEEE 754

Hi! What is the way to get the binary representation of a IEEE 754 (like 0001110110001111010101100111001011100100101010111101) without using perl. Bash for example, would be fine. I need to put that representation in a string for some operation and then to put that string back in a float. ... (3 Replies)
Discussion started by: Zephyr
3 Replies
Login or Register to Ask a Question