C 如何将浮点变量自动升级为双精度类型?

C 如何将浮点变量自动升级为双精度类型?,c,floating-point,double,ieee-754,type-promotion,C,Floating Point,Double,Ieee 754,Type Promotion,我知道在C和Java中,float的底层表示是IEEE754-32,double是IEEE754-64 在表达式中,float将自动升级为double。那怎么办? 以3.7f为例。这个过程是这样的吗 3.7f将使用IEEE754在内存中表示。它可以容纳4个字节 在计算过程中,可以将其加载到64位寄存器(或任何64位位置),将3.7f转换为IEEE754-64 它非常依赖于实现 例如,在x86平台上,FPU命令集包括用于加载/存储IEEE754float和double格式(以及许多其他格式)数据的

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

在表达式中,
float
将自动升级为
double
。那怎么办? 以3.7f为例。这个过程是这样的吗

  • 3.7f将使用IEEE754在内存中表示。它可以容纳4个字节
  • 在计算过程中,可以将其加载到64位寄存器(或任何64位位置),将3.7f转换为IEEE754-64

  • 它非常依赖于实现

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


    这意味着在x86平台上没有单步浮点到双精度的转换。每当需要这种转换时,它实际上被实现为两步转换:浮点到内部fpu和内部fpu到double

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

    几年前,FPU单元还是x86平台的可选组件。无FPU平台上的浮点计算是在软件中执行的,可以通过模拟FPU,也可以通过生成代码而不使用任何FPU指令。在这种实现中,事情可能会不同,例如,直接执行从IEEE754
    float
    到IEEE754
    double
    的软件转换

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

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

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


    不过,在Java或C语言中也是如此,因为它们在虚拟机中运行字节码,并且虚拟机的类型在不同平台上是一致的

    那么IEEE754格式转换在哪里和什么时候发生?因为你说FPU使用80位表示,而不是IEEE754。@larmbr:我不确定我是否理解你的问题。在现代x86上,转换是在CPU/FPU内部实现的。FPU命令可以将IEEE数据从内存读入80位寄存器并存储回内存。任何必要的转换相关步骤都作为硬件和/或微码在CPU/FPU内部实现。“这意味着在x86平台上没有单步浮点到双精度转换。”这取决于x86的哪个版本,现代x86芯片有两组独立的浮点指令。正如您所描述的,老式的x87指令和直接处理单精度和双精度浮点的SSE指令。我知道在C/Java中,浮点数的底层表示是IEEE754-32,双精度表示是IEEE754-64。没有所谓的“浮点”或“两点”
    float
    double
    是许多语言中的两种浮点类型,通常映射到IEEE-754中的
    单精度
    (也称二进制32)和
    双精度
    (也称二进制64)。也没有像IEEE754-32和IEEE754-64这样的东西
    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.