c++ - 為什麼printf()會將float提升為double?




floating-point variadic-functions (3)

因為(C99或 C11 )標準是這樣說的。 請參閱 2501的答案 。

這有幾個實用的原因:歷史記錄(C的第一個實現已用於系統編程,而浮點運算無關緊要),以及在當前(平板電腦,台式機,服務器...)處理器上進行算術運算的事實 double 上的運算與 float 一樣高效(但是一些便宜的微控制器沒有FPU,或者只能通過硬件添加 float ,並且對 double 上的每個運算都需要一個庫)。 最後,我想這樣的規則可以使 調用約定 ABI 稍微簡單一些。

float 視為某種 short double float 型(在C中,這當然是 非法 的)。 float 在需要壓縮內存的情況下最有用(並且可能會損失精度)。 另請參見 http://floating-point-gui.de/

從上一個 question

如果您嘗試將 float 傳遞給 printf ,則在 printf 收到 double 之前,它將被提升為 double

printf() 是可變函數嗎? 那麼,可變參數函數是否在將 float 參數傳遞給 double 之前將其提升為 double


是的,可變參數函數的float參數被提升為兩倍。

C99標準草案 6.5.2.2 節“函數調用”中指出:

[...]和float類型的參數被提升為double。 這些被稱為默認參數提升。[...]

C ++標準草案 5.2.2 節調用:

浮點類型受浮點提升(4.6)的限制,參數值在調用之前轉換為提升的類型。 [...]

和第 4.6 節:

可以將float類型的prvalue轉換為double類型的prvalue。 值不變

cppreference 很好地介紹了C ++中可變參數函數的 默認轉換

  • std :: nullptr_t轉換為void *
  • 浮點參數轉換為浮點升級中的double
  • bool,char,short和unscoped枚舉將轉換為int或更寬的整數類型,如整數提升

我們可以在C語言中(大概在C ++中)看到這種轉換是為了與 K&R C 兼容,這是從 國際標準-編程語言-C 強調我的 )的基礎上:

為了與過去的做法兼容,所有參數提升都按照K&R中的描述在沒有原型聲明的情況下發生, 包括並非總是希望將float提升為double


至於問題的部分 原因 ,很簡單:C(和C ++)標準將 double 視為“默認”浮點類型。 不是 float (這是我們許多程序員在使用浮點數時的默認值)。

通過觀察可以看出:

  1. 3.14double float (如果需要 float ,則必須多做一步並附加 f
  2. 默認情況下,標準數學函數默認為 double (例如, sin()double ;如果要 float 運算,則必須使用 sinf()

這樣,由於 double 是語言中的“自然”默認值,因此在可變參數函數調用中將 float 提升為 double 似乎更為“自然”。





variadic-functions