簡體   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