C:将浮点传递给函数

时间:2013-05-18 22:36:44

标签: c android-ndk

鉴于以下内容......

void test(){
  float a = 0.7f;
  LOGD("Width %.1f",0.7f);
  LOGD("Width %.1f",a);
  fark(a);
}

void fark(float test){
  LOGD("Width %.1f",test);
}

这输出......

  

05-18 22:35:25.215:D / Native(8241):宽度0.7

     

05-18 22:35:25.215:D / Native(8241):宽度0.7

     

05-18 22:35:25.215:D / Native(8241):宽度36893488147419103232.0

我对最后一个错过了什么?

1 个答案:

答案 0 :(得分:12)

您需要在使用前声明fark。如第6.5.2.2节第6段所述:

  

如果表示被调用函数的表达式具有不包含原型的类型,则对每个参数执行整数提升,并将类型为float的参数提升为{{1} } 即可。这些被称为默认参数促销

(我大胆强调)。

请注意,使用与隐式假定类型不兼容的类型定义double是违反约束的,并且如果调用和定义位于同一转换单元中,则需要编译器发出诊断消息。 gcc只会警告,但是clang会拒绝代码[fark]。如果调用和定义在不同的翻译单元中,编译器当然不能诊断错误,但是通过具有不兼容类型的表达式调用函数在任何情况下都会调用未定义的行为。

当值error: conflicting types for 'fark'转换为0.7f时(我假设double使用IEEE754 32位表示,float使用IEEE754 64位表示法,你得到一个值

double

其位模式(十六进制表示法)为

0.699999988079071

(偏差指数为1022,对应有效指数0x3FE6666660000000 ,有效数为-1)。

将其传递到堆栈或寄存器 - 1.6666660000000

fark从该表示中读取32位时 - 因为它期望每个定义fark - 取决于float的传递方式,它可能会读取更高阶32位或低位32。

在这种情况下确实读取了低位32位,导致带有位模式的double

float

的偏差指数为0x60000000 ,对应于无偏指数0xC0 = 192和有效数192 - 127 = 65。换句话说,那是

1.000000表示
float

这是打印的值。