【问题标题】:C: Passing floating point to functionC:将浮点传递给函数
【发布时间】:2013-05-18 22:36:43
【问题描述】:

鉴于以下...

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

关于最后一个,我错过了什么?

【问题讨论】:

  • 这不是 C 问题。它在我的笔记本电脑上运行良好。也许fark() 的声明有所不同?
  • 谢谢,我会调查的
  • 我错了:结果在我的机器上它也不起作用 - 我修复了定义的顺序。

标签: c android-ndk


【解决方案1】:

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

如果表示被调用函数的表达式的类型不包含原型,则对每个参数执行整数提升,类型为 float 的参数提升为 double。这些被称为默认参数提升

(我加粗强调)。

请注意,使用与隐式假定类型不兼容的类型定义 fark 是违反约束的,并且如果调用和定义位于同一翻译单元中,则需要编译器发出诊断消息。 gcc 仅在那时发出警告,但 clang 拒绝代码 [error: conflicting types for 'fark']。如果调用和定义在不同的翻译单元中,编译器当然不能诊断错误,但是通过类型不兼容的表达式调用函数无论如何都会调用未定义的行为。

当值 0.7f 转换为 double(我假设 float 使用 IEEE754 32 位表示,double IEEE754 64 位表示),你得到一个值

0.699999988079071

其位模式(以十六进制表示)是

0x3FE6666660000000

(偏置指数为1022,对应有效指数-1,有效指数为1.6666660000000)。

这被传递 - 在堆栈或寄存器中 - 到 fark

fark 从该表示中读取 32 位时 - 因为它根据其定义期望 float - 取决于 double 的传递方式,它可能读取高阶 32 位或低阶32.

在这种情况下,它确实读取了低位 32 位,从而产生了具有位模式的 float

0x60000000

它有一个有偏指数0xC0 = 192,对应于无偏指数192 - 127 = 65和有效数1.000000。换句话说,就是float的表示

2^65 = 36893488147419103232

这是打印的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-14
    • 2017-03-22
    • 2015-09-16
    • 2023-03-21
    • 2021-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多