1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時(shí)間:8:30-17:00
      你可能遇到了下面的問(wèn)題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
      float和double(我內(nèi)存里的浮點(diǎn)型數(shù)據(jù)?)

      二更,因?yàn)楹脦讉€(gè)人因?yàn)檫@篇文章把我批斗了,把有問(wèn)題的地方修正。

      公司主營(yíng)業(yè)務(wù):成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作、移動(dòng)網(wǎng)站開(kāi)發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開(kāi)放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來(lái)驚喜。創(chuàng)新互聯(lián)推出焉耆免費(fèi)做網(wǎng)站回饋大家。

      今天看到一個(gè)問(wèn)題

      能不能用 double 去取代 float ?

      前段時(shí)間,有個(gè)朋友問(wèn)我,在 java 里面我想把一個(gè)高精度的浮點(diǎn)型存儲(chǔ)下來(lái),但是每次存儲(chǔ)的時(shí)候都會(huì)被強(qiáng)制降低精度,對(duì)于浮點(diǎn)型的理解,真的非常非常重要,特別對(duì)嵌入式軟件開(kāi)發(fā),或者算法開(kāi)發(fā),涉及到數(shù)據(jù)類的,浮點(diǎn)型非常非常關(guān)鍵,就比如,微信為什么不讓我發(fā) 0.0000000001 元的微信紅包呢? 有沒(méi)有想過(guò)這個(gè)問(wèn)題?如果這樣做對(duì)于他們服務(wù)器后臺(tái)的運(yùn)算能力要求非常高, so , ~~~~~

      所以想簡(jiǎn)單寫(xiě)一下, float 和 double 的區(qū)別以及應(yīng)用場(chǎng)景

      float 和 double (我內(nèi)存里的浮點(diǎn)型數(shù)據(jù)?)

      1 、浮點(diǎn)型的值范圍

      float 和 double 的范圍是由指數(shù)的位數(shù)來(lái)決定的。在 VC++6.0 中, float 占 4 個(gè)字節(jié), double 占 8 個(gè)字節(jié)。

      Type Storage size Value range 

      float 4 byte 1.2E-38 to 3.4E+38

      double 8 byte 2.3E-308 to 1.7E+308

      long double 10 byte 3.4E-4932 to 1.1E+4932

      2 、浮點(diǎn)型在內(nèi)存里面是如何存儲(chǔ)的?

      我相信這個(gè)問(wèn)題大家沒(méi)有好好的去考慮過(guò),浮點(diǎn)型如何存儲(chǔ),這才是我們討論浮點(diǎn)型的關(guān)鍵所在,關(guān)于上面的浮點(diǎn)型取值范圍,也是網(wǎng)上拷貝下來(lái)的,至于真實(shí)性,我覺(jué)得你們要看了這部分才可能真正理解浮點(diǎn)型,而且最好在自己的編譯器去測(cè)試,浮點(diǎn)型是可以等于負(fù)數(shù)的,所以上面的范圍,你們認(rèn)為是正確的嗎?

      float 和 double (我內(nèi)存里的浮點(diǎn)型數(shù)據(jù)?)

      我拿 float 來(lái)舉個(gè)栗子:

      float 和 double (我內(nèi)存里的浮點(diǎn)型數(shù)據(jù)?)

      float 在內(nèi)存中的存儲(chǔ)方式

      以下 部分如發(fā)現(xiàn)問(wèn)題,請(qǐng)留言,會(huì)發(fā)小小紅包感謝,微信 weiqifa0

      首先使用基數(shù) 2 而不是基數(shù) 10 來(lái)表示科學(xué)計(jì)數(shù)法變體中的浮點(diǎn)值。例如,值 3.14159 可以表示為

      1.570795 * 2^{1}

      1.570795 是 有效數(shù)字又名尾數(shù)(在上圖中指尾數(shù)部分) ; 它是包含有效數(shù)字的數(shù)字的一部分。此值乘以基數(shù) 2 ,上升到 1 的冪,得到 3.14159 。

      浮點(diǎn)數(shù)通過(guò)存儲(chǔ) 有效數(shù)和指數(shù)(以及符號(hào)位) 進(jìn)行編碼。

      典型的 32 位布局如下所示:

       3 32222222 22211111111110000000000

       1 09876543 21098765432109876543210

      +-+--------+-----------------------+

      | |        |                       |

      +-+--------+-----------------------+

       ^    ^                ^

       |    |                |

       |    |                +-- 有效數(shù)  

       |    |

       |    +------------------- 指數(shù)

       |

       +------------------------ 符號(hào)位

      與有符號(hào)整數(shù)類型一樣,高位表示符號(hào) ; 表示 值, 1 表示 負(fù) 值。

      而對(duì)于指數(shù)部分,因?yàn)橹笖?shù)可正可負(fù), 8 位的指數(shù)位能表示的指數(shù)范圍就應(yīng)該為 :-127-128 了, 所以指數(shù)部分的存儲(chǔ)采用移位存儲(chǔ), 存儲(chǔ)的數(shù)據(jù)為元數(shù)據(jù) +127

      舉例:

      float 和 double (我內(nèi)存里的浮點(diǎn)型數(shù)據(jù)?)

      剩余的比特用于有效數(shù)字。每個(gè)位表示從左側(cè)算起的 2 的負(fù)冪, float 一共 23 ,舉例:

      float 和 double (我內(nèi)存里的浮點(diǎn)型數(shù)據(jù)?)

      某些平臺(tái)假定有效數(shù)中的 “ 隱藏 ” 前導(dǎo)位始終設(shè)置為 1 ,因此有效數(shù)中的值始終在 [0.5,1 之間 ] 。這允許這些平臺(tái)以稍高的精度存儲(chǔ)值。

      所以 3.14159 的值將表示為

          0 10000000 10010010000111111010000

          ^ ^        ^

          | |        |

          | |        + --- 有效數(shù) = 1.570795 ...

          | |

          | + ------------------- 指數(shù) = 2 ( 130  -  128 )

          |

          + ------------------------- sign = 0 (正面)

          value = 1 (符號(hào)位) * 2 (指數(shù)位) * (有效數(shù)字)

          值 = 1 0 * 2^1 * 1.570795 ...

          值 = 3.14159 ......

      現(xiàn)在,如果你將有效數(shù)字中的所有位相加,你會(huì)注意到它們總共 不是 3.14195 ;

      他們實(shí)際上 3.141590118408203125 ,(小編實(shí)測(cè)數(shù)據(jù))

      沒(méi)有足夠的位來(lái)準(zhǔn)確存儲(chǔ)值 ; 我們只能存儲(chǔ)一個(gè)近似值。有效數(shù)字中的位數(shù)決定了精度 23 位給出了大約 6 位精度的十進(jìn)制數(shù)字 。 64 位浮點(diǎn)類型在有效位數(shù)中提供足夠的位, 可提供大約 12 15 位的精度 。但要注意,有一些數(shù)值不能被精確表示。就像 1/3 這樣的值不能用有限數(shù)量的十進(jìn)制數(shù)字表示,由于值是近似值,因此使用它們進(jìn)行計(jì)算也是近似值,并且累積誤差會(huì)累積。

      float 和 double (我內(nèi)存里的浮點(diǎn)型數(shù)據(jù)?)

      #include

      void main ( void )

      {

          for ( float i = ; i < 1 ;i += 0.01 )

          {

              printf( "%f \r\n" ,i);

          }

          for ( double i = ; i < 1 ;i += 0.01 )

          {

              printf( "%f\r\n" ,i);

          }

          for ( long double i = ; i < 1 ;i += 0.01 )

          {

              printf( "%Lf\r\n" ,i);

          }

      }

      注意其中輸出

      float 和 double (我內(nèi)存里的浮點(diǎn)型數(shù)據(jù)?)

      到 0.830000 之后明顯出現(xiàn)了誤差

      float 和 double (我內(nèi)存里的浮點(diǎn)型數(shù)據(jù)?)

      3 、反向驗(yàn)證第二點(diǎn)的存儲(chǔ)推斷

      上面的計(jì)算,我們可以通過(guò)一個(gè)小代碼反向驗(yàn)證,代碼如下

      #include

      int main ()

      {

          /*0b1000000010010010000111111010000*/

          float num = 3.14159f ;

          int * p = ( int * ) & num;

          printf( "0x%x\n" , * p);

          return ;

      }

      float 和 double (我內(nèi)存里的浮點(diǎn)型數(shù)據(jù)?)

      輸出 16 進(jìn)制數(shù)據(jù)

      so~~~~

      3.14159 0x40490fd0 = 0 10000000 10010010000111111010000

      float 和 double (我內(nèi)存里的浮點(diǎn)型數(shù)據(jù)?)

      16 進(jìn)制對(duì)應(yīng)二進(jìn)制數(shù)據(jù)

      對(duì)于 double 和 long double 的大小和精度可以通過(guò)這個(gè)方式來(lái)驗(yàn)證。

      float 和 double (我內(nèi)存里的浮點(diǎn)型數(shù)據(jù)?)

      4 、浮點(diǎn)型 printf 輸出格式

      printf 輸出范圍 %f %g %Lf %e

      #include

      void main ( void )

      {

          float f_sum = ;

          double d_test = ;

          

          f_sum = - 3.4 * 10e-38 ;

          d_test = - 1.7 * 10e-308 ;

          printf( "%.38f\r\n" ,f_sum);

          printf( "%.308f\r\n" ,d_test);

          printf( "%g\r\n" ,f_sum);

          printf( "%g\r\n" ,d_test);

          

          f_sum = 3.4 * 10e37 ;

          d_test = 1.7 * 10e307 ;

          printf( "%g\r\n" ,f_sum);

          printf( "%g\r\n" ,d_test);

      }

      輸出如下

      weiqifa@ubuntu:~/c/float$ gcc float.c && a.out

      -0.00000000000000000000000000000000000034

      -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017

      -3.4e-37

      -1.7e-307

      3.4e+38

      1.7e+308

      weiqifa@ubuntu:~/c/float$

      float 和 double (我內(nèi)存里的浮點(diǎn)型數(shù)據(jù)?)

      5 精度問(wèn)題

      浮點(diǎn)數(shù)在內(nèi)存中是按科學(xué)計(jì)數(shù)法來(lái)存儲(chǔ)的,其整數(shù)部分始終是一個(gè)隱含著的 "1" ,由于它是不變的,故不能對(duì)精度造成影響。

      float : 2^23 = 8388608 ,一共七位,這意味著最多能有 7 位有效數(shù)字,但絕對(duì)能保證的為 6 位,也即 float 的精度為 6~7 位有效數(shù)字;

      double : 2^52 = 4503599627370496 ,一共 16 位,同理, double 的精度為 15~16 位。

      float 和 double (我內(nèi)存里的浮點(diǎn)型數(shù)據(jù)?)

      小代碼舉例

      #include "stdio.h"

      int main ( void )

          float fa = 1.0f ; 

          float fb = - 2.123456789f ; 

          float fc = 3.999999f ; 

          double da = 1.0 ; 

          double db = - 4.0000000 ; 

          double dc = 3.123456789012345 ; 

          printf( "%-32.32f \r\n%-32.32f \r\n%-32.32f\r\n" ,fa,fb,fc);

          printf( "%-64.64f \r\n%-64.64f \r\n%-64.64f\r\n" ,da,db,dc);

          return

      輸出

      1.00000000000000000000000000000000 

      -2.12345671653747558593750000000000 

      3.99999904632568359375000000000000

      1.0000000000000000000000000000000000000000000000000000000000000000 

      -4.0000000000000000000000000000000000000000000000000000000000000000 

      3.1234567890123448030692543397890403866767883300781250000000000000

      float 和 double (我內(nèi)存里的浮點(diǎn)型數(shù)據(jù)?)

      6 、浮點(diǎn)值和 “0”

      不知道大家對(duì)精度是怎么看的,理論上浮點(diǎn)是永遠(yuǎn)不可能等于 “0” 的,只能無(wú)盡接近于 “0” ,所以你拿浮點(diǎn)型 和 “0” 比較 ,千萬(wàn)千萬(wàn)不要用 “== ” 恒等于符號(hào),而是用大小于符號(hào),精度越大,說(shuō)明越無(wú)盡接近于 “0” ,有時(shí)候 float 的精度容易引起問(wèn)題,看下面的例子。 --- 之前寫(xiě)的,下面論證是否正確

      評(píng)論已經(jīng)有人說(shuō),浮點(diǎn)值肯定可以等于 1 ,這個(gè)不再做論證,現(xiàn)在論證浮點(diǎn)值和 值,是不是相等的。

      所以,我做了實(shí)驗(yàn),我的文章不一定保證正確,但是提出的觀點(diǎn)一定要有論證的根據(jù)

      晚上回來(lái)很累,跟楠哥睡了一下, 10 點(diǎn)的時(shí)候,楠哥又起來(lái)了,我也想更新下評(píng)論的問(wèn)題,我測(cè)試的代碼如下,里面有注釋。

      #include "stdio.h"

      int main()

      {

              /*0b01000000010010010000111111010000  3.14159 的二進(jìn)制 */

      /*0b00111111100000000000000000000000  1 的二進(jìn)制 */

      //int it = 0b01000000010010010000111111010000;

      int it = 0b00111111100000000000000000000000;

              float *num = (float*)⁢

      float num1;

      int *p = (int *)&num1;

      printf("%f\r\n",*num);/* 輸出我們認(rèn)為是 0 的二進(jìn)制數(shù)值 */

      printf("%f\r\n",num1);/* 未初始化的 float 值 */

      printf("0x%x\r\n",*p);/* 打印里面的內(nèi)容 */

      /* 里面的內(nèi)容是 0x401980 */

      /* 轉(zhuǎn)成 二進(jìn)制是 0b 0100 0000 0001 1001 1000 0000*/

      /* 這樣好看點(diǎn) 0b 0 10000000 001100110000000*/

      int it2 = 0x401980;

      float *num3 = (float *)&it2;

      /* 分別用三種方式輸出 */

      printf("%f\r\n",*num3);

      printf("%-32.32f\r\n",*num3);

      printf("%d\r\n",(int)*num3);

          return 0;

      }

      輸出如下圖

      float 和 double (我內(nèi)存里的浮點(diǎn)型數(shù)據(jù)?)

      float 和 double (我內(nèi)存里的浮點(diǎn)型數(shù)據(jù)?)

      7 、總結(jié)

      1 、浮點(diǎn)型在內(nèi)存里面的存儲(chǔ)方式

      2 、浮點(diǎn)型的精度問(wèn)題

      3 、浮點(diǎn)型的


      本文標(biāo)題:float和double(我內(nèi)存里的浮點(diǎn)型數(shù)據(jù)?)
      轉(zhuǎn)載注明:http://www.ef60e0e.cn/article/ppohic.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        井研县| 彭泽县| 务川| 渭南市| 美姑县| 普定县| 大港区| 五华县| 淄博市| 古田县| 弥勒县| 两当县| 尼勒克县| 新竹市| 远安县| 锡林浩特市| 宜城市| 来宾市| 沂源县| 大足县| 涪陵区| 手机| 沅江市| 永新县| 枣庄市| 平顶山市| 石首市| 永嘉县| 延长县| 南澳县| 定西市| 瑞昌市| 牙克石市| 新安县| 津市市| 志丹县| 泰兴市| 富顺县| 沙田区| 西华县| 临邑县|