使C浮点字面量浮动(而不是双精度)


76

众所周知,在C中,浮点文字(例如1.23)具有type double。结果,任何涉及它们的计算都将提高一倍。

我正在一个嵌入式实时系统上工作,该系统的浮点单元仅支持单精度(float)数字。我所有的变量都是float,并且这种精度已经足够。我根本不需要(也负担不起)double。但是每次

if (x < 2.5) ...

写作中,灾难发生了:减速可能高达两个数量级。当然,直接的答案是写

if (x < 2.5f) ...

但这很容易错过(并且很难检测到为时已晚),尤其是当#define由缺乏纪律(或只是新手)的开发人员在单独的文件中输入“配置”值时。

因此,是否有一种方法可以强制编译器将所有(浮点数)文字视为float,就像带有后缀一样f?即使违反规范,我也不在乎。或其他解决方案?顺便说一下,编译器是gcc。


30
-Wdouble-promotion,至少会给您警告。结合-Wfloat-conversion应能提供很好的覆盖率。
布雷特·黑尔

3
这并不能直接回答您的问题,但是编写脚本以仅插入fFP文字中缺少的s并没有那么困难。
Xophmeister


4
某些嵌入式系统的编译器将double映射为float,仅启用带选项的double precision。我不知道海湾合作委员会(GCC)是否有类似的内容
phuclv

3
@BrettHale该评论值得一个适当的答案。我认为,在这种情况下,获得警告比其他一些允许程序员编写与标准不兼容的代码的编译器选项更具生产力。
user694733

Answers:


83

-fsingle-precision-constant可以使用标志。即使不精确,它也会导致以单精度加载​​浮点常量。

注意-这还将在对双精度变量进行运算时使用单精度常量。


2
谢谢!我不知道这个标志。这完美地回答了我的问题-即使像其他人建议的那样,生成警告可能更为谨慎。
宙斯

@宙斯高兴它帮助了!:)
ameyCU 2015年

2
我会明智地使用此选项!考虑一个新开发人员,只需键入x < 2.5,一切都会好起来的。他可能会错过那个可以节省生命的特定编译器选项:-)。相反-Wdouble-promotion,当他(使用,-Wfloat-conversion)获取警告时,并且使用-Werror它将所有警告转换为错误时,他可能不会直接检入代码,可能会疑惑并学习。但是,仅出于发行质量的考虑,您可能希望保持安全,并使用特定选项(-fsingle-precision-constant)对其进行编译。请注意,这只是一条评论。
数学

52

改为使用警告:如您的示例中所示,-Wdouble-promotion隐式浮点数加倍促销发出警告。-Wfloat-conversion会警告您仍然可能为浮点数分配双精度的情况。

与简单地将double值强制为最接近的float值相比,这是一个更好的解决方案。您的浮点代码仍然符合要求,并且如果双精度值保持正值(例如,小于FLT_DENORM_MIN(假设IEEE-754)或大于),则不会有任何令人讨厌的惊喜FLT_MAX


一般来说,您是对的。但是,在我的特定情况下-fsingle-precision-constant效果更好。首先,我的GCC版本(4.4.7)根本没有这些选项。其次,除了NaN之外,我没有任何棘手的常量,而且所有计算都必须是float正则表达式(这是重点)。最终,提供的芯片库生成了很多警告(其中大多数是明确的!),以至于有用的警告经常被埋在堆里。而且,正如我所说,在这种情况下,我不太担心严格遵守。
宙斯

2
我也相信使用命令开关仅隐藏源代码中的问题是危险的。只需考虑一下您的代码可能会在五年后使用新版本的编译器供其他人使用,也许没有那么巧妙的选择。修复源代码中的问题比隐藏它们更可取。关于所有这些警告...在进行生产编译时,应将警告视为错误。-Werror :-)
ChrisB

1

您可以将定义的常量(float)强制转换为使用它们的任何位置,优化器应完成其工作。这是一个便携式解决方案。

#define LIMIT 2.5

if (x < (float)LIMIT) ...

或将其
强制转换

2
@CuriousRabbit:不能解决“纪律性较差(或只是新手)开发人员”的问题。
Yves Daoust 2015年

1

-Wunsuffixed-float-constants标志也可以使用,也可以与上面接受的答案中的其他一些选项组合使用。但是,这可能不会在系统标头中捕获未加前缀的常量。也将需要使用-Wsystem-headers来捕获那些。可能会产生很多警告...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.