簡體   English   中英

為什么 numeric_limits<float> ::min() 實際上沒有給出盡可能小的浮點數?

[英]Why does numeric_limits<float>::min() not actually give the smallest possible float?

似乎我們可以輕松地推導出小於numeric_limits<float>::min() 為什么。 如果numeric_limits<float>::min()不應該是最小的正浮點數,它應該是什么?

#include <iostream>
#include <limits>
using namespace std;

int main(){
    float mind = numeric_limits<float>::min();
    float smaller_than_mind = numeric_limits<float>::min()/2;
    cout<< ( mind > smaller_than_mind && smaller_than_mind > 0 ) <<endl;
}

在此處運行: https : //onlinegdb.com/ry3AcxjXz

浮點類型的min()返回具有格式完整表達能力的最小正值——其有效數的所有位均可用。

較小的正值稱為次正常值。 盡管它們是可表示的,但有效數的高位必須為零。

IEEE-754 64 位二進制浮點格式表示帶有符號(+ 或 -,編碼為 0 或 1)、指數(-1022 到 +1023,編碼為 1 到 2046,加上 0 和 2047)的數字特殊情況)和 53 位有效數(用 52 位加上指數字段中的線索編碼)。

對於正常值,指數字段是 1 到 2046(代表 -1022 到 +1023 的指數),有效數(二進制)是 1.xxx…xxx,其中 xxx…xxx 代表 52 位以上。 在所有這些值中,有效數的最低位的值是最高有效位(其中的第一個 1)的值的 2 -52倍。

對於次正規值,指數字段為 0。這仍然表示指數為 -1022,但表示有效數的高位為 0。有效數現在為 0.xxx...xxx。 隨着在此范圍內使用越來越低的值,有效數的更多前導位變為零。 現在,有效數的最低位的值大於最高有效位的值的 2 -52倍。 在此區間中,您無法像在正常區間中那樣精細地調整數字,因為並非所有有效位的位都可用於任意值——一些前導位固定為 0 以設置比例。

因此,在處理此范圍內的數字時出現的相對誤差往往大於正常范圍內的相對誤差。 浮點格式具有這個次正常范圍,因為如果沒有,數字將在最小的正常值處截斷,並且該正常值和零之間的差距將是一個巨大的相對跳躍——100%一步。 通過包含次正規數,相對誤差逐漸增加,並且絕對誤差從這一點開始保持恆定直到達到零。

重要的是要知道正常范圍的底部在哪里。 min()告訴你這個。 denorm_min()告訴您最終的最小正值。

根據en.cppreference.com

對於具有非規范化的浮點類型, min 返回最小正規范化值。 請注意,此行為可能出乎意料,尤其是與整數類型的 min 行為相比時。

float是一種非規范化類型,有關規范化浮點數的信息

因為numeric_limits::min返回“對於具有次正規數的浮點類型,返回最小正標准化值。” 您可以將其除以 2 並在某些系統上獲得一個次正規(在某些平台上也稱為正規)數字。 這些數字不存儲float類型的完整精度,但允許存儲否則將變為 0.0 的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM