繁体   English   中英

为什么GCC警告这种隐式转换?

[英]Why does GCC warn against this implicit conversion?

GCC警告我,以下代码包含可能更改值的隐式转换:

#include <stdlib.h>
float square = rand();

但是,以下内容不会产生任何警告:

float square = 100;

海湾合作委员会发出的警告如下:

tests/ChemTests.cpp:17:23: error: conversion to ‘float’ from ‘int’ may alter its value

我不明白为什么前者会发出警告,因为rand()被正确声明并返回一个int ,就像100整数文字一样。

为什么第一行给出编译器警告而不是第二行,即使两者都有从intfloat的隐式转换?

当演员阵容导致精度损失时,GCC会发出此警告。 (换句话说,价值可能会被“改变”)

在第一种情况下, rand()返回一个int 由于并非所有可以存储在int中的值都可以表示为float ,因此它将发出此警告。

在第二种情况下,100可以安全地铸造到float而没有任何精度损失。

要添加的东西是什么Mysticial写的(这是正确的):你的C的实现使用float32位IEEE 754单精度二进制浮点int是32位。 在“your” int您可以拥有31位数字和1位符号。 在“你的”浮点数中, mantissa是24位,有1位符号。 显然int需要超过24位的加号表示不能准确地转换“你的” S float (我使用“你的”代表你的编译器,你正在使用的编译器.C标准没有告诉floatint的确切长度。

现在, rand()可以生成任何int数,因此编译器必须向您发出警告。 100是在编译时已知的数字文字,因此编译器可以静态检查该数字是否可转换。

(即使没有详细解释浮点如何工作,你的int是32位并且“仅支持”整数。你的float是32位并且“支持”浮点数。显然浮点数更难以表示(你必须保存)在小数点为的地方,所以如果intfloat都有相同的长度,你必须支付“价格”。价格是精确的。)

要响应您所做的评论,您可以在“连续”为0的float中精确表示的最大数字(因此0 ...数字都可以完全表示)是16777215(尾数= 16777215,指数= 0) )和16777216(尾数= 1,指数= 24,因为它是1 * 2 ^ 24)。 16777217无法准确描述。 16777218是。

并非每个int都可以表示为float 具体来说,如果int设置的最高位和最低位之间的位数大于<float.h>定义的FLT_MANT_DIG - 1 ,则它不能精确表示为float (对于doubleDBL_MANT_DIG - 1 。)编译器警告您可能存在精度损失,因为rand()的声明意味着rand()可以返回任何int ,包括那些不能表示为float int

gcc应该足够聪明,以便知道何时可以精确表示int文字:

float f= 1<<FLT_MANT_DIG; // yes
float g= (1<<FLT_MANT_DIG) - 1; // yes
float h= (1<<FLT_MANT_DIG) + 1; // no
float i= (1<<(FLT_MANT_DIG + 1)); // yes

gcc应该吐出警告来初始化h

顺便提一下,如果RAND_MAX小于或等于(1<<FLT_MANT_DIG) - 1 ,你可以安全地将rand()分配给一个float ,即使编译器向你抱怨也是如此。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM