[英]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
整數文字一樣。
為什么第一行給出編譯器警告而不是第二行,即使兩者都有從int
到float
的隱式轉換?
當演員陣容導致精度損失時,GCC會發出此警告。 (換句話說,價值可能會被“改變”)
在第一種情況下, rand()
返回一個int
。 由於並非所有可以存儲在int
中的值都可以表示為float
,因此它將發出此警告。
在第二種情況下,100可以安全地鑄造到float
而沒有任何精度損失。
要添加的東西是什么Mysticial寫的(這是正確的):你的C的實現使用float
是32位IEEE 754單精度二進制浮點和int
是32位。 在“your” int
您可以擁有31位數字和1位符號。 在“你的”浮點數中, mantissa
是24位,有1位符號。 顯然int
需要超過24位的加號表示不能准確地轉換“你的” S float
。 (我使用“你的”代表你的編譯器,你正在使用的編譯器.C標准沒有告訴float
或int
的確切長度。
現在, rand()
可以生成任何int
數,因此編譯器必須向您發出警告。 100
是在編譯時已知的數字文字,因此編譯器可以靜態檢查該數字是否可轉換。
(即使沒有詳細解釋浮點如何工作,你的int
是32位並且“僅支持”整數。你的float
是32位並且“支持”浮點數。顯然浮點數更難以表示(你必須保存)在小數點為的地方,所以如果int
和float
都有相同的長度,你必須支付“價格”。價格是精確的。)
要響應您所做的評論,您可以在“連續”為0的float
中精確表示的最大數字(因此0 ...數字都可以完全表示)是16777215(尾數= 16777215,指數= 0) )和16777216(尾數= 1,指數= 24,因為它是1 * 2 ^ 24)。 16777217無法准確描述。 16777218是。
並非每個int
都可以表示為float
。 具體來說,如果int
設置的最高位和最低位之間的位數大於<float.h>
定義的FLT_MANT_DIG - 1
,則它不能精確表示為float
。 (對於double
和DBL_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.