Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C : how is double number (e.g. 123.45) stored in a float variable or double variable or long double variable?

Tags:

c

#include <stdio.h>

int main () {
float a = 123.0; 

unsigned char ch, *cp;
ch = 0xff;

cp = (unsigned char *) &a;
printf ("%02x", ch&(*(cp+3)));
printf ("%02x", ch&(*(cp+2)));
printf ("%02x", ch&(*(cp+1)));
printf ("%02x\n", ch&(*(cp+0)));

/*I have written this program to see binary representation, but I can not understand the output, the binary representation?
}
like image 231
Sudarshan Roy Avatar asked Dec 21 '22 11:12

Sudarshan Roy


2 Answers

See Wikipedia: http://en.wikipedia.org/wiki/Single_precision_floating-point_format, which describes single precision floating point (a typical C float, but depends on the compiler) as a 1-bit sign, 8-bit biased exponent, and 24-bit mantissa (23-bits stored).

For your example:

123.0 = 42f60000hex = 0 10000101 11101100000000000000000bin
1-bit sign = 0 (indicating positive number)
8-bit biased exponent = 10000101bin = 133dec - 127dec = 6dec
23-bit mantissa = 11101100000000000000000bin = 1.111011bin (note implied leading 1)

Converting 1.111011bin x 26dec = 1111011.0bin = 123.0dec

like image 60
Mark Tolonen Avatar answered Dec 31 '22 07:12

Mark Tolonen


Guessing about your question how is double number (e.g. 123.45) stored in a float variable or double variable or long double variable?: If you store a double-value (like the literal "123.0") into a float variable, the compiler will static_cast<float> the value so it becomes a valid float value.

So, apart from possible compiler warnings, the following

int main () {
    float foo = 123.0;
}

is basically the same as

int main () {
    float foo = static_cast<float>(123.0);
}

If you want to explicitly state a float-literal, use the f or F postfix:

int main () {
    float foo = 123.0f; // alternatively: 123.f, 123.F
}

edit: From the Standard

Just looked up the grammar for floating-literals, for the curious:

floating-literal:
    fractional-constant exponent-part_opt floating-suffix_opt
    digit-sequence exponent-part floating-suffix_opt

fractional-constant:
    digit-sequence_opt . digit-sequence
    digit-sequence .

exponent-part:
    e sign_opt digit-sequence
    E sign_opt digit-sequence

Here some examples for floating-point literals that require no conversion (but possibly rounding):

float a = 1.f,
      b = 1.0f,
      c = .0f,
      d = 1e1f,
      e = 1.e1f,
      f = 1e-1f,
      g = 1e+1f,
      h = 1E+1F;

If conversion is needed, e.g.

float a = 1., // double
      b = 1.L,// long double
      c = 1;  // integer

The following applies:

4.8 Floating point conversions [conv.double]

An rvalue of floating point type can be converted to an rvalue of another floating point type. If the source value can be exactly represented in the destination type, the result of the conversion is that exact representation. If the source value is between two adjacent destination values, the result of the conversion is an implementation-defined choice of either of those values. Otherwise, the behavior is undefined.

4.9 Floating-integral conversions_ [conv.fpint]:

An rvalue of an integer type or of an enumeration type can be converted to an rvalue of a floating point type. The result is exact if possible. An rvalue of an integer type or of an enumeration type can be converted to an rvalue of a floating point type. The result is exact if possible. Otherwise, it is an implementation-defined choice of either the next lower or higher representable value.

So in summary, if you put a literal of type double or long double (or some integer) into a float, the compiler will implicitly convert that value, if it can be converted exactly. Otherwise, it is platform-dependent how the result is stored; in case the value exceeds the representable range, you enter the world of undefined behaviour *.


* The Dreaded Realm of Undefined Behaviour, where an evil compiler writer may find it funny to beep out an infernal sound through your loudspeakers and make you bleed through the ears, and still be sanctioned by the standard (not necessarily by local laws, though).

like image 24
Sebastian Mach Avatar answered Dec 31 '22 08:12

Sebastian Mach