Internal representation of double


 
Thread Tools Search this Thread
Top Forums Programming Internal representation of double
# 1  
Old 09-10-2010
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:

Code:
#include <stdio.h> 
#include <stdlib.h> 
main(int argc, char *argv[])
{
  unsigned char *ch = NULL;
  char  seq1[] = {   0,   0,    0, 128,  20, 174,  27,  64 };
  char  seq2[] = {174, 71, 225, 122,  20, 174,  27,  64 };
  const int sz = sizeof(double);
  int   i = 0;
  double d = 6.92;
        printf("d=%.6f\t:\t", d);
        ch = (unsigned char *)&d;
        for(i = 0; i < sz; i++)
        {
                printf("%u ", *ch++);
        }
        printf("\n");
        ch = (unsigned char *)&d; d = 0;
        for(i = 0; i < sz; i++)
                *ch++ = seq1[i];
        printf("1) d=%.6f\n", d);
        ch = (unsigned char *)&d; d = 0;
        for(i = 0; i < sz; i++)
                *ch++ = seq2[i];
        printf("2) d=%.6f\n", d);
        return(0);
}

and results are:

Code:
d=6.920000      :       174 71 225 122 20 174 27 64 
1) d=6.920000
2) d=6.920000

How is that possible?
# 2  
Old 09-10-2010
The internal representation of floating-point numbers is a well-documented standard.

As for why two things can represent identical numbers, it's because of how the number works: A number times a base to an exponent. You could represent 256 with 1 * 2^8, or 2 * 2^7, etc.

Usually though these numbers would be normalized into the first, simplest form to ensure greatest accuracy in numeric operations.
These 5 Users Gave Thanks to Corona688 For This Post:
# 3  
Old 09-15-2010
Whatever compiler you are using is broken...get a newer one. Besides you are trying to print a double as a float with only 6 digits of precision so you can guess what happens if the exponent is a very large negative number and change the printf to
Code:
printf("d = %.6e", d);

# 4  
Old 09-16-2010
The difference between float and double is nil as far as printf's concerned, they get promoted to double these days when they get passed as varargs.
# 5  
Old 09-17-2010
Actually SEQ1 and SEQ2 are different IEEE 754 binary64 numbers according to my calculations with SEQ2 being the "correct" answer.

SEQ1: 0 0 0 0 128 20 174 27 64 = 401BAE1480000000 = 6.9200000762939450

Bit 62 (Sign bit) 0 (+)
Bits 62 - 52 (Exponent) 10000000001 = 1025 - 1023 = 2
Bits 51 - 0 (Significand) 1 .1011101011100001010010000000000000000000000000000000 = 1.7300000190734863


SEQ2: 174 71 225 122 20 174 27 64 = 401BAE147AE147AE = 6.9200000000000000

Bit 62 (Sign bit) 0 (+)
Bits 62 - 52 (Exponent) 10000000001 = 1025 - 1023 = 2
Bits 51 - 0 (Significand) 1 .1011101011100001010001111010111000010100011110101110 = 1.7300000000000000

The printf format precision (%.6f) masked the difference.
This User Gave Thanks to fpmurphy For This Post:
# 6  
Old 09-17-2010
Quote:
Originally Posted by Corona688
The difference between float and double is nil as far as printf's concerned, they get promoted to double these days when they get passed as varargs.
Except when it comes to the degree of precision desired...old compilers used to automatically convert floats to doubles but that is no longer practised and if that is indeed the case then all the more reason to use the double format specification instead of the float.

---------- Post updated at 02:59 PM ---------- Previous update was at 01:59 PM ----------

Quote:
Originally Posted by fpmurphy
Actually SEQ1 and SEQ2 are different IEEE 754 binary64 numbers according to my calculations with SEQ2 being the "correct" answer.

SEQ1: 0 0 0 0 128 20 174 27 64 = 401BAE1480000000 = 6.9200000762939450

Bit 62 (Sign bit) 0 (+)
Bits 62 - 52 (Exponent) 10000000001 = 1025 - 1023 = 2
Bits 51 - 0 (Significand) 1 .1011101011100001010010000000000000000000000000000000 = 1.7300000190734863


SEQ2: 174 71 225 122 20 174 27 64 = 401BAE147AE147AE = 6.9200000000000000

Bit 62 (Sign bit) 0 (+)
Bits 62 - 52 (Exponent) 10000000001 = 1025 - 1023 = 2
Bits 51 - 0 (Significand) 1 .1011101011100001010001111010111000010100011110101110 = 1.7300000000000000

The printf format precision (%.6f) masked the difference.
Its good you posted the results as I was getting confused why my systems were reporting different...so it is an endianness issue and here are the results from an AIX and HPUX machine which are both big endian.
Code:
d = 2.7178687957231882e-312    (0x0000008014ae1b40)     /*  seq1  */

d = -9.6037214055361180e-86    (0xae47e17a14ae1b40)     /*  seq2  */

# 7  
Old 09-17-2010
Quote:
Originally Posted by shamrock
Except when it comes to the degree of precision desired...old compilers used to automatically convert floats to doubles but that is no longer practised and if that is indeed the case then all the more reason to use the double format specification instead of the float.
I'm not saying float and double are the same. I'm saying %f is capable of handling double-precision numbers.

Consider that %f works with doubles and floats even though they're different sizes. stdargs has no way to warn printf which is used, so the compiler must be converting them to something consistent. So if double-precision works in printf at all, they're all being passed as doubles, and all being used as doubles, not floats.
Login or Register to Ask a Question

Previous Thread | Next Thread

8 More Discussions You Might Find Interesting

1. 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

2. UNIX and Linux Applications

Graphical Representation of mpstat.out file

hi everyone, We've generated mpstat.out file monitoring cpu utilization and the file is ready now.Wanted to generate graphical charts for the same output data. Can anyone pleas suggest tool for the same.? (1 Reply)
Discussion started by: Kathraji
1 Replies

3. Homework & Coursework Questions

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,... (5 Replies)
Discussion started by: robin_simple
5 Replies

4. Shell Programming and Scripting

Convert a matrix to sparse representation

Hi All, I have a matrix stored in a file matrix.mtx and looks like this: 1 0.5 0.33 0.25 0 0.33 0.25 0.2 0 0 0 0.16 0 0 0 0.14 I want to convert this matrix to its sparse representation like the one give below (sparse_matrix.mtx). This means that above matrix has been converted to its... (1 Reply)
Discussion started by: shoaibjameel123
1 Replies

5. Programming

problems with pointers and internal representation.

I am trying to implement the representation in the attached file. class matriz { private: int fil,col; int **filaspointer; int *buffer; public: matriz(); matriz(int fil,int col); ... (3 Replies)
Discussion started by: lamachejo
3 Replies

6. Shell Programming and Scripting

Question on file owner name representation

Hi All, I came across a situation where i saw a directory name given below: drwxrwxrwx 5 121973 staff 8192 Apr 26 23:47 arunpr Just for your info: 1. All our application user ids are LDAP. 2. Hence we will not see any details of user in /etc/passwd file and i believe this could... (6 Replies)
Discussion started by: Arunprasad
6 Replies

7. UNIX for Advanced & Expert Users

Forwarding internal internet packets to internal webserver using iptables

Hi, I need to redirect internal internet requests to a auth client site siting on the gateway. Currently users that are authenticated to access the internet have there mac address listed in the FORWARD chain. All other users need to be redirected to a internal site for authentication. Can... (1 Reply)
Discussion started by: mshindo
1 Replies

8. Solaris

Disk Representation - what is this c1t1d0s2 represent?

Hi All, Can you please advise what the 't' letters stands for? I understand the letter for the following "c1t1d0s2": c = disk Controller t = ? d = disk number ID. s = slice or partition of the disk Thanks (2 Replies)
Discussion started by: tlee
2 Replies
Login or Register to Ask a Question