17

当我在程序中初始化float变量时,我通常有如下向量:

Vector forward(0.f,0.f,-1.f),right(1.f,0.f,0.f),up(0.f,1.f,0.f)

(向量只是 3 个浮点数,如struct Vector{ float x,y,z; };

这看起来容易阅读为:

Vector forward(0,0,-1),right(1,0,0),up(0,1,0)

我必须使用s初始化我的float变量吗?float当我使用整数(或doubles)初始化 a时,我是否会丢失任何东西或招致某种惩罚float

4

3 回答 3

12

两者之间没有语义差异。但是,根据某些编译器,可能会生成额外的代码。另请参阅同一主题的这个这个SO 问题。

我可以确认gcc为所有变体生成相同的代码

int main()
{
    float a = 0.0f; /* or 0 or 0.0 */
    return 0;
}

并且这段代码是

    .file   "1.c"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $0x00000000, %eax
    movl    %eax, -4(%rbp)
    movl    $0, %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
    .section    .note.GNU-stack,"",@progbits

相关线路是

    movl    $0x00000000, %eax

更改a0.1(或0.1f)将行更改为

    movl    $0x3dcccccd, %eax

似乎gcc能够推断出正确的常数并且不会生成额外的代码。

于 2012-09-28T09:49:31.880 回答
7

对于单个文字常量,这无关紧要。在初始化器的上下文中,任何数字类型的常量都将被隐式转换为正在初始化的对象的类型。这是由语言标准保证的。所以所有这些:

float x = 0;
float x = 0.0;
float x = 0.0f;
float x = 0.0L;   // converted from long double to float

同样有效并导致相同的值存储在x.

但是,更复杂的表达式中的文字常量可能会产生令人惊讶的结果。

在大多数情况下,每个表达式都是由自身计算的,而不管它出现在什么上下文中。在评估子表达式应用任何隐式转换。

所以如果你写:

float x = 1 / 2;

该表达式1 / 2将被评估为int,产生0,然后转换为float. It will setx to0.0f , not to0.5f`。

我认为使用无后缀浮点常量(类型为double)应该是安全的。

顺便说一句,您可能会考虑使用double而不是float在您的程序中。double正如我所提到的,它是无后缀浮点常量的类型,在某种意义上可以被认为是“默认”浮点类型。它通常比 具有更大的范围和精度float,并且通常在性能上没有太大差异。

于 2013-05-23T19:27:36.893 回答
2

It could be a good programming practise to always write 0.f, 1.f etc., even if often gcc can figure out what the programmer means by 1.0 et al.

The problematic cases are not so much trivial float variable initializations, but numeric constants in somewhat more complex formulae, where a combination of operators, float variables and said constants can easily lead to occurrence of unintended double valued calculations and costly float-double-float conversions.

Spotting these conversions without specifically checking the compiled code for them becomes very hard if the intended type for numeric values is mostly omitted in the code and instead only included when it's absolutely required. Hence I for one would choose the approach of just typing in the f's and getting used to having them around.

于 2013-05-23T19:08:46.933 回答