【问题标题】:C : how is double number (e.g. 123.45) stored in a float variable or double variable or long double variable?C:双数(例如 123.45)如何存储在浮点变量或双变量或长双变量中?
【发布时间】:2011-06-30 22:20:56
【问题描述】:
#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?
}

【问题讨论】:

标签: c


【解决方案1】:

参见 Wikipedia:http://en.wikipedia.org/wiki/Single_precision_floating-point_format,它将单精度浮点(典型的 C float,但取决于编译器)描述为 1 位符号、8 位偏置指数和 24 位尾数(23 - 位存储)。

你的例子:

123.0 = 42f60000hex = 0 10000101 11101100000000000000000bin
1 位符号 = 0(表示正数)
8 位偏置指数 = 10000101bin = 133dec - 127dec = 6dec
23 位尾数 = 11101100000000000000000bin = 1.111011bin(注意隐含前导 1)

转换 1.111011bin x 26dec = 1111011.0bin = 123.0dec

【讨论】:

  • 为什么 123.0 会转换成 42f60000 hex?不应该是007B吗?
  • @Liyanage 这是一个如何存储单精度浮点的示例。 007B是整数 123的存储方式。阅读整个答案和提供的链接。请注意,答案的最后一行是 1111011.0,即 7B 十六进制的二进制。
【解决方案2】:

猜测您的问题how is double number (e.g. 123.45) stored in a float variable or double variable or long double variable?:如果您将双值(如文字“123.0”)存储到浮点变量中,编译器将 static_cast&lt;float&gt; 该值因此它变成有效的浮点值。

因此,除了可能的编译器警告之外,以下

int main () {
    float foo = 123.0;
}

基本一样

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

如果您想显式声明浮点文字,请使用 fF 后缀:

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

编辑:来自标准

只是为好奇的人查找了浮动文字的语法:

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

这里有一些不需要转换(但可能是四舍五入)的浮点字面量示例:

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

如果需要转换,例如

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

以下适用:

4.8 浮点转换 [conv.double]

浮点类型的右值可以转换为另一种浮点类型的右值。如果源 value 可以在目标类型中精确表示,转换的结果就是那个精确的表示。 如果源值介于两个相邻的目标值之间,则转换结果为 这些值中的任何一个的实现定义的选择。否则,行为未定义。

4.9 浮点积分转换_ [conv.fpint]:

整数类型或枚举类型的右值可以转换为浮点类型的右值。如果可能,结果是准确的。整数类型或枚举类型的右值可以转换为浮点的右值 类型。如果可能,结果是准确的。否则,它是下一个实现定义的选择 更低或更高的可表示值。

总而言之,如果您将doublelong double(或某个整数)类型的文字放入float,编译器将隐式转换该值,如果它可以被精确转换的话。否则,结果的存储方式取决于平台;如果值超出可表示的范围,您将进入未定义行为的世界*


* 未定义行为的可怕领域,邪恶的编译器编写者可能会觉得通过扬声器发出地狱般的声音并让你流血,但仍然受到标准(但不一定符合当地法律)。

【讨论】:

  • 如何使用static_cast&lt;&gt; 转换像“123.0”这样的字符串文字?
  • @Constantinius:已更新。几乎每个值,右值或左值,都可以转换:)
【解决方案3】:

要了解浮点变量的二进制布局是如何工作的,我建议您阅读相应标准化的wikipedia article

简而言之,所有浮点数(floatdoublelong double,分别是 half 的实现)都由一个尾数和一个表示数字的指数组成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-27
    • 2014-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多