欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語(yǔ)言float內(nèi)存布局示例詳解

 更新時(shí)間:2023年09月12日 10:38:40   作者:不停感嘆的老林  
這篇文章主要為大家介紹了C語(yǔ)言float內(nèi)存布局示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

C語(yǔ)言中的float并不像大多數(shù)人想象的那樣, 由于計(jì)算機(jī)模擬的原因, 其本質(zhì)是離散的而非連續(xù)的, 所以精度和范圍是一定的, 這些都寫在float.h頭文件的宏中.

但通常, 我們對(duì)教材的每一個(gè)字都認(rèn)識(shí), 連起來就讀不懂了, 所以, 寫下此博文, 詳解之.

學(xué)過深入理解計(jì)算機(jī)系統(tǒng)的同學(xué), 都知道float的實(shí)現(xiàn)方式, 按照IEEE標(biāo)準(zhǔn), 由符號(hào)位, 階碼位, 尾數(shù)位組成, 本文給出一個(gè)代碼, 打印float的符號(hào)位, 階碼位, 尾數(shù)位.

一、float中的宏定義

這是float.h中有關(guān)float具體實(shí)現(xiàn), 范圍, 精度等的宏常量, 依據(jù)64位系統(tǒng)環(huán)境, 我們逐個(gè)解讀.

#include <float.h>
    FLT_RADIX;      // 2;
    FLT_MANT_DIG;   // 24;
    FLT_DIG;        // 6;
    FLT_MIN_10_EXP; // (-37);
    FLT_MAX_10_EXP; // 38;
    FLT_EPSILON;    // 1.19209290e-7F;
    FLT_MAX;        // 3.40282347e+38F;
    FLT_MIN;        // 1.17549435e-38F;

FLT_RADIX 2

This is the value of the base, or radix, of the exponent representation. This is guaranteed to be a constant expression, unlike the other macros described in this section. The value is 2 on all machines we know of except the IBM 360 and derivatives.

這是指數(shù)表示的基數(shù)或基數(shù)的值。這保證是一個(gè)常量表達(dá)式,與本節(jié)中描述的其他宏不同。在我們所知的所有機(jī)器上,該值均為 2,除了 IBM 360 及其衍生產(chǎn)品。

float基于二進(jìn)制實(shí)現(xiàn), 其基數(shù)是2.

換句人話說, 所有float浮點(diǎn)數(shù), 都是由一系列2的n次方相加組成.

比如

0.5 就是
2^-1 次方,

0.25就是
2^-2 次方,

0.75就是
2^-1 + 2^-2

FLT_MANT_DIG 24

This is the number of base-FLT_RADIX digits in the floating point mantissa for the float data type. The following expression yields 1.0 (even though mathematically it should not) due to the limited number of mantissa digits:

這是浮點(diǎn)數(shù)據(jù)類型的浮點(diǎn)尾數(shù)中的基數(shù)FLT_RADIX位數(shù)。由于尾數(shù)位數(shù)有限,以下表達(dá)式產(chǎn)生 1.0(盡管在數(shù)學(xué)上不應(yīng)該產(chǎn)生):

float radix = FLT_RADIX; // 2.0
1.0f + 1.0f / radix / radix / … / radix; //在float中, 1.0 其實(shí)是 1.0 + 1.0 連續(xù)除以 24 個(gè) 2.0

where radix appears FLT_MANT_DIG times.

radix 出現(xiàn)了FLT_MANT_DIG 次, 也就是 24 次.

這個(gè)細(xì)節(jié)如果有人看過深入理解操作系統(tǒng), 那么就應(yīng)該明白了, 在IEEE標(biāo)準(zhǔn)中, float的尾數(shù)是23位, 但由于通常都是1.0+0.N的形式, 所以相當(dāng)于第一位是隱式的1, 加23位就是24位.

這24位就是float的二進(jìn)制精度.

FLT_DIG 6

float的十進(jìn)制精度, 包括整數(shù)部分及小數(shù)部分.

比如 123.456 這就是6位精度, 再多就不保證精度可用了, 比如123.4567, 其中7就不保證是正確的.

FLT_MIN_10_EXP (-37)

這代表float能保證的最小的10進(jìn)制指數(shù), 我這里是 10^-37 次方, 再小就不保證正確了.

FLT_MAX_10_EXP 38

這是float能保證的最大的10進(jìn)制指數(shù), 再大就不保證正確了

FLT_EPSILON 1.19209290e-7F

這個(gè)不好理解, 它的意思是 1.0 和比 1.0 大的最小的float值的差.

FLT_MAX 3.40282347e+38F

float能表示的最大數(shù).

FLT_MIN 1.17549435e-38F

float能表示的最小數(shù).

二、float 內(nèi)存布局打印實(shí)現(xiàn)算法

基本思想是實(shí)現(xiàn)一個(gè)位域結(jié)構(gòu), 將一個(gè)32位的整數(shù)分成三份, 一份占1位, 指示符號(hào), 一份占8位, 指示階碼, 一份占23位, 指示尾數(shù).

typedef struct
{
    uint32_t Mantissa : 23;
    uint32_t Exponent : 8;
    uint32_t Sign : 1;
} fltToBit;

由于是小端序, 逆著排, 也就是尾數(shù), 階碼, 符號(hào).

通過itoa()函數(shù), 將整數(shù)轉(zhuǎn)為二進(jìn)制字符串, 并進(jìn)行打印.

float 內(nèi)存布局打印實(shí)現(xiàn)代碼

代碼比較容易, 唯一不好理解的是:

fltToBit test = *(fltToBit *)&a;

float 不能直接強(qiáng)制轉(zhuǎn)為 fltToBit, 需要先取地址, 強(qiáng)轉(zhuǎn)為 fltToBit 指針, 再解引用.

其他的代碼都應(yīng)該能懂.

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
    uint32_t Mantissa : 23;
    uint32_t Exponent : 8;
    uint32_t Sign : 1;
} fltToBit;
void print_float_as_binary(float a)
{
    char BufExponet[32] = "";
    char BufMantissa[32] = "";
    fltToBit test = *(fltToBit *)&a;
    printf("Sign: %u\nExponent: %08s\nMantissa: %023s\n", test.Sign,
           itoa(test.Exponent, BufExponet, 2),
           itoa(test.Mantissa, BufMantissa, 2));
}
int main()
{
    const float a = 1.4142136F;
    print_float_as_binary(a);
    return 0;
}

總結(jié)

float 是用離散方法實(shí)現(xiàn)有限精度的浮點(diǎn)數(shù), 有時(shí)間應(yīng)仔細(xì)查閱文檔進(jìn)行推敲, 很有意思.

本文介紹了IEEE對(duì)float的實(shí)現(xiàn), 利用數(shù)據(jù)結(jié)構(gòu), 將其內(nèi)部真實(shí)二進(jìn)制值打印出來, 方便讀者研究。

更多關(guān)于C語(yǔ)言float內(nèi)存布局的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • c++實(shí)現(xiàn)的常見緩存算法和LRU

    c++實(shí)現(xiàn)的常見緩存算法和LRU

    LRU緩存算法也叫LRU頁(yè)面置換算法,是一種經(jīng)典常用的頁(yè)面置換算法,下面這篇文章主要介紹了c++實(shí)現(xiàn)的常見緩存算法和LRU,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-01-01
  • C++ list-map鏈表與映射表的簡(jiǎn)單使用

    C++ list-map鏈表與映射表的簡(jiǎn)單使用

    本文主要介紹了C++ list-map鏈表與映射表的簡(jiǎn)單使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • C++如何刪除map容器中指定值的元素詳解

    C++如何刪除map容器中指定值的元素詳解

    map容器是C++ STL中的重要一員,刪除map容器中value為指定元素的問題是我們經(jīng)常與遇到的一個(gè)問題,下面這篇文章主要給大家介紹了關(guān)于利用C++如何刪除map容器中指定值的元素的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-06-06
  • C語(yǔ)言動(dòng)態(tài)內(nèi)存分配圖文講解

    C語(yǔ)言動(dòng)態(tài)內(nèi)存分配圖文講解

    給數(shù)組分配多大的空間?你是否和初學(xué)C時(shí)的我一樣,有過這樣的疑問。這一期就來聊一聊動(dòng)態(tài)內(nèi)存的分配,讀完這篇文章,你可能對(duì)內(nèi)存的分配有一個(gè)更好的理解
    2023-01-01
  • 詳解C語(yǔ)言之實(shí)現(xiàn)通訊錄

    詳解C語(yǔ)言之實(shí)現(xiàn)通訊錄

    這篇文章主要為大家詳細(xì)介紹了用C語(yǔ)言實(shí)現(xiàn)通訊錄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • C++中智能指針unique_ptr的實(shí)現(xiàn)詳解

    C++中智能指針unique_ptr的實(shí)現(xiàn)詳解

    智能指針本質(zhì)上并不神秘,其實(shí)就是?RAII?資源管理功能的自然展現(xiàn)而已,這篇文章主要為大家詳細(xì)介紹了如何實(shí)現(xiàn)?C++中智能指針的?unique_ptr,需要的可以了解下
    2024-01-01
  • C++數(shù)組去重十種方法

    C++數(shù)組去重十種方法

    數(shù)組去重是一個(gè)常見的操作,本文主要介紹了C++數(shù)組去重十種方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-03-03
  • C++中std::find函數(shù)介紹和使用場(chǎng)景

    C++中std::find函數(shù)介紹和使用場(chǎng)景

    std::find函數(shù)是一個(gè)非常實(shí)用的通用查找算法,適用于各種場(chǎng)景,本文主要介紹了C++中std::find函數(shù)介紹和使用場(chǎng)景,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-02-02
  • VScode運(yùn)行C++中文終端亂碼的解決方案

    VScode運(yùn)行C++中文終端亂碼的解決方案

    這篇文章主要介紹了VScode運(yùn)行C++中文終端亂碼的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • C語(yǔ)言中pthread_exit和pehread_join的使用

    C語(yǔ)言中pthread_exit和pehread_join的使用

    pthread_exit用于強(qiáng)制退出一個(gè)線程,pthread_join用于阻塞等待線程退出,獲取線程退出狀態(tài),本文主要介紹了C語(yǔ)言中pthread_exit和pehread_join函數(shù)的使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-02-02

最新評(píng)論