4

当您需要整数值并且整数文字无论如何都会隐式转换为双精度/浮点时,为什么要使用双精度或浮点文字?并且当需要小数值时,为什么还要添加f(以制作浮点文字)无论如何都会将双精度数转换为浮点数?

比如我经常看到类似下面的代码

float foo = 3.0f;
double bar = 5.0;
// And, unfortunately, even
double baz = 7.0f;

void quux(float foo) {
     ...
}

...

quux(7.0f);

但据我所知,这些相当于

float foo = 3;
// or
// float foo = 3.0;
double bar = 5;
double baz = 7;
quux(9);

如果您使用重载语言(c ++,java),我可以理解方法调用,如果函数重载(或将来),它实际上可以产生功能差异,但我更关心C(并且在较小程度上是Objective-C),它没有重载。

那么有什么理由打扰额外的小数和/或f吗?特别是在初始化的情况下,声明的类型在哪里

4

4 回答 4

4

很多人通过艰难的方式学会了

double x = 1 / 3;

没有按预期工作。所以他们(包括我自己)通过使用浮点文字而不是依赖隐式转换来防御性地编程。

于 2014-05-27T21:14:58.810 回答
3

C 没有重载,但它有一些称为可变参数函数的东西。这就是.0问题所在。

void Test( int n , ... )
{
    va_list list ;
    va_start( list , n ) ;
    double d = va_arg( list , double ) ;
    ...
}

调用函数而不指定数字是双精度数将导致未定义的行为,因为 va_arg 宏会将变量内存解释为双精度数,而实际上它是一个整数。

Test( 1 , 3 ) ;必须Test( 1 , 3.0 ) ;


但你可能会说;我永远不会写可变参数函数,那何必呢?

printf( 和 family ) 是可变参数函数。

该调用应生成警告:

printf("%lf" , 3 ) ;   //will cause undefined behavior

但是根据警告级别、编译器和忘记包含正确的标头,您根本不会收到任何警告。

如果切换类型,也会出现问题:

printf("%d" , 3.0 ) ;    //undefined behaviour
于 2014-05-27T20:35:47.707 回答
2

当您需要整数值并且整数文字无论如何都会隐式转换为双精度/浮点时,为什么要使用双精度或浮点文字?

首先,“隐式转换”是矛盾的(根据定义,转换是显式的)。您正在寻找的表达式是“隐式 [类型] 转换”。

至于为什么:因为它更明确(没有双关语)。如果您对文字的类型有一些视觉指示,这对眼睛和大脑会更好。

为什么还要添加 f (以制作浮点文字),无论如何都会将双精度转换为浮点数?

例如,因为doublefloat具有不同的精度。由于浮点很奇怪并且通常不直观,如果您不手动指定类型,则从doubleto (这是有损的)转换可能会导致与您实际想要的值不同的值。floatfloat

于 2014-05-27T21:25:50.840 回答
0

In most cases, it's simply a matter of saying what you mean.

For example, you can certainly write:

#include <math.h>
...
const double sqrt_2 = sqrt(2);

and the compiler will generate an implicit conversion (note: not a cast) of the int value 2 to double before passing it to the sqrt function. So the call sqrt(2) is equivalent to sqrt(2.0), and will very likely generate exactly the same machine code.

But sqrt(2.0) is more explicit. It's (slightly) more immediately obvious to the reader that the argument is a floating-point value. For a non-standard function that takes a double argument, writing 2.0 rather than 2 could be much clearer.

And you're able to use an integer literal here only because the argument happens to be a whole number; sqrt(2.5) has to use a floating-point literal, and

My question would be this: Why would you use an integer literal in a context requiring a floating-point value? Doing so is mostly harmless, since the compiler will generate an implicit conversion, but what do you gain by writing 2 rather than 2.0? (I don't consider saving two keystrokes to be a significant benefit.)

于 2014-05-27T21:45:00.573 回答