4

我知道在 C 和 Java 中,float 的底层表示是 IEEE754-32,double 是 IEEE754-64。

在表达式中,float将自动提升为double. 又怎样?以 3.7f 为例。过程是这样的吗?

  1. 3.7f 将使用 IEEE754 在内存中表示。它适合 4 个字节。
  2. 在计算过程中,它可能会被加载到一个 64 位寄存器(或任何 64 位位置),将 3.7f 转换为 IEEE754-64 表示。
4

2 回答 2

5

它非常依赖于实现。

例如,在 x86 平台上,FPU 命令集包括以 IEEE754floatdouble格式(以及许多其他格式)加载/存储数据的命令。数据被加载到具有 80 位宽度的内部 FPU 寄存器中。所以实际上在 x86 上,所有浮点计算都是以 80 位浮点精度执行的。即所有浮点数据实际上都提升为 80 位精度。这些寄存器中的数据如何表示完全无关紧要,因为无论如何您都无法直接观察它们。

这意味着在 x86 平台上不存在单步浮点到双精度转换之类的东西。每当需要这种转换时,它实际上是作为两步转换实现的:float-to-internal-fpu 和 internal-fpu-to-double。

这个 BTW 在 x86 FPU 计算模型和 C/C++ 计算模型之间产生了显着的语义差异。为了完全匹配语言模型,处理器必须强制降低中间浮点结果的精度,从而对性能产生负面影响。许多编译器为用户提供控制 FPU 计算模型的选项,允许用户选择严格的 C/C++ 一致性、更好的性能或介于两者之间的选项。

就在几年前,FPU 单元还是 x86 平台的可选组件。无 FPU 平台上的浮点计算是在软件中执行的,要么通过模拟 FPU,要么通过生成完全没有任何 FPU 指令的代码。在这样的实现中,事情可能会有所不同,例如,直接执行从 IEEE754float到 IEEE754的软件转换double

于 2012-08-25T03:00:35.693 回答
0

我知道在 C/Java 中,浮点数的底层表示是 IEEE754-32,双点是 IEEE754-64。

错误的。C 标准从未指定整数和浮点类型大小的固定、特定限制,尽管它们确实确保了类型之间的关系

1 == sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)
sizeof(float) <= sizeof(double) <= sizeof(long double)

尽管现在大多数使用 IEEE-754 及其后代格式,但 C 实现允许使用任何类型的浮点格式。同样,他们可以自由使用任何整数表示,例如 1 的补码或符号大小

关于提升规则,C 的预标准版本将表达式中的浮点数提升为双倍,但在 C89/90 中,规则已更改并float * float产生float结果。

If either operand has type long double, the other operand is converted to long double
Otherwise, if either operand is double, the other operand is converted to double.
Otherwise, if either operand is float, the other operand is converted to float.

C++ 运算符中的隐式类型转换规则

但在 Java 或 C# 中确实如此,因为它们在虚拟机中运行字节码,并且 VM 的类型跨平台是一致的

于 2013-12-19T14:42:15.953 回答