C#中32位浮點(diǎn)數(shù)Float實(shí)例代碼分析

這篇文章主要介紹“C#中32位浮點(diǎn)數(shù)Float實(shí)例代碼分析”,在日常操作中,相信很多人在C#中32位浮點(diǎn)數(shù)Float實(shí)例代碼分析問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對(duì)大家解答”C#中32位浮點(diǎn)數(shù)Float實(shí)例代碼分析”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!

我們提供的服務(wù)有:網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、微信公眾號(hào)開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、朔州ssl等。為1000多家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的朔州網(wǎng)站制作公司

我們都知道單精度浮點(diǎn)數(shù)(Single,float,Real)由32位0或1組成,它具體是如何來的。

浮點(diǎn)數(shù)的32位N=1符號(hào)位(Sign)+8指數(shù)位(Exponent)+23尾數(shù)部分(Mantissa)

  • 符號(hào)位(Sign) : 0代表正,1代表為負(fù)【占1位】

  • 指數(shù)位(Exponent)::用于存儲(chǔ)科學(xué)計(jì)數(shù)法中的指數(shù)數(shù)據(jù),并且采用移位存儲(chǔ)【占8位】

  • 尾數(shù)部分(Mantissa):尾數(shù)部分【占23位】

  • 單精度float:N共32位,其中S占1位,E占8位,M占23位。因此小數(shù)點(diǎn)后最多精確到23/4=6位 。

C#代碼示例如下

using System;
using System.Collections.Generic;
using System.Linq;
namespace ConverterAndPrecisionDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //參考博客:https://blog.csdn.net/zhengyanan815/article/details/78550073
            //小數(shù)點(diǎn)后面:4個(gè)位占用一個(gè)數(shù)字【十進(jìn)制9就是1001】
            //符號(hào)位(Sign) : 0代表正,1代表為負(fù)【占1位】
            //指數(shù)位(Exponent):用于存儲(chǔ)科學(xué)計(jì)數(shù)法中的指數(shù)數(shù)據(jù),并且采用移位存儲(chǔ)【占8位】
            //尾數(shù)部分(Mantissa):尾數(shù)部分【占23位】
            //單精度float:N共32位,其中S占1位,E占8位,M占23位。因此小數(shù)點(diǎn)后最多精確到23/4=6位 
            //雙精度double:N共32位,其中S占1位,E占11位,M占52位。因此小數(shù)點(diǎn)后最多精確到52/4=13位 
            //十進(jìn)制小數(shù)的二進(jìn)制表示:【法則--整數(shù)部分:除基取余,逆序拼接。小數(shù)部分:乘基取整,順序拼接】
            //整數(shù)部分:除以2,取出余數(shù),商繼續(xù)除以2,直到得到0為止,將取出的余數(shù)逆序。可以使用棧Stack
            //小數(shù)部分:乘以2,然后取出整數(shù)部分,將剩下的小數(shù)部分繼續(xù)乘以2,然后再取整數(shù)部分,一直取到小數(shù)部分為零為止。如果永遠(yuǎn)不為零,則按要求保留足夠位數(shù)的小數(shù),最后一位做0舍1入。將取出的整數(shù)順序排列。可以使用隊(duì)列Queue
            float f = 123456.8125F;
            byte[] buffer = BitConverter.GetBytes(f);
            Console.WriteLine("打印浮點(diǎn)數(shù)對(duì)應(yīng)的4個(gè)字節(jié):");
            Console.WriteLine(string.Join(",", buffer));
            Console.WriteLine($"【使用函數(shù)】{123456}對(duì)應(yīng)的二進(jìn)制:{ Convert.ToString(123456, 2)}");
            int num = 123456;
            Stack<int> stack = new Stack<int>();
            while (num != 0)
            {
                int cur = num % 2;
                stack.Push(cur);
                num = num / 2;
            }
            Console.WriteLine($"【使用堆?!縶123456}對(duì)應(yīng)的二進(jìn)制:{ string.Join("", stack)}");
            int scale = 10;
            int index = 0;
            double d = 0.8125;
            Queue<int> queue = new Queue<int>();
            while (index < scale)
            {
                int cur = (int)(d * 2);
                queue.Enqueue(cur);
                d = d * 2 - cur;
                if (d == 0)
                {
                    break;
                }
                index++;
            }
            Console.WriteLine($"{0.8125}對(duì)應(yīng)的二進(jìn)制:{ string.Join("", queue)}");
            string binaryDisplay = string.Join("", stack) + "." + string.Join("", queue);
            Console.WriteLine($"{123456.8125}對(duì)應(yīng)的二進(jìn)制為{binaryDisplay}");
            int dotIndex = binaryDisplay.IndexOf('.');
            //移除小數(shù)點(diǎn)后將小數(shù)點(diǎn)插入索引1的位置【即:小數(shù)點(diǎn)移動(dòng)到索引1的位置】
            string scienceDisplay = binaryDisplay.Remove(dotIndex, 1).Insert(1, ".");
            Console.WriteLine($"小數(shù){123456.8125}對(duì)應(yīng)的二進(jìn)制科學(xué)計(jì)數(shù)為{scienceDisplay}×(2的{dotIndex - 1}次方)");
            string sign = (f > 0 ? "0" : "1");//符號(hào)位占用1位
            Console.WriteLine($"符號(hào)位S:正數(shù)為0,負(fù)數(shù)為1。符號(hào)位是:{sign}");
            string exponent = Convert.ToString(127 + (dotIndex - 1), 2).PadLeft(8, '0');//指數(shù)位占用8位
            Console.WriteLine($"指數(shù)位E:123456最高位為2的{dotIndex - 1}次方,指數(shù)為{dotIndex - 1},因此指數(shù)位E的十進(jìn)制值為【127+{dotIndex - 1}={127 + dotIndex - 1}】");
            //尾數(shù)部分:去除scienceDisplay開始的"1.",也就是字符串從索引2開始。并湊夠23位
            string mantissa = scienceDisplay.Substring(2).PadRight(23, '0');//尾數(shù)位占用23位
            Console.WriteLine($"尾數(shù)位M:尾數(shù)部分M需要湊夠23位。為【{mantissa}】");
            string joinBits = sign + exponent + mantissa;//符號(hào)位占用1位+指數(shù)位占用8位+尾數(shù)位占用23位=32位
            byte[] bufferJoin = new byte[4];
            for (int i = 0; i < 4; i++)
            {
                bufferJoin[i] = Convert.ToByte(joinBits.Substring(8 * i, 8), 2);
            }
            Console.WriteLine("重新拼接形成的32位浮點(diǎn)數(shù),對(duì)應(yīng)的4個(gè)字節(jié)為:");
            Console.WriteLine(string.Join(",", bufferJoin));
            byte[] reverseBuffer = bufferJoin.Reverse().ToArray();
            Console.WriteLine("反轉(zhuǎn)數(shù)組bufferJoin的順序:重新打印我們會(huì)發(fā)現(xiàn)與浮點(diǎn)數(shù)原始的字節(jié)完全一致。注意:C#是低字節(jié)在前");
            Console.WriteLine(string.Join(",", reverseBuffer));
            Console.ReadLine();
        }
    }
}

程序運(yùn)行結(jié)果

C#中32位浮點(diǎn)數(shù)Float實(shí)例代碼分析

關(guān)于32位浮點(diǎn)數(shù)的一些理解

1、定點(diǎn)的缺點(diǎn)

對(duì)于一個(gè)系統(tǒng)可能出現(xiàn)一些特別大的數(shù)和特別小的數(shù),如果用定點(diǎn)表示就會(huì)很僵硬,位數(shù)一定就不能同時(shí)表達(dá)特別大的數(shù)和特別小的數(shù)。

2、對(duì)于定點(diǎn)123.625

用科學(xué)計(jì)數(shù)法的方式可以寫成1.23625*10^2,也可以寫成12.625*10^1或1.111011101*2^6。。。。。為了規(guī)范,IEEE就規(guī)定了32位浮點(diǎn)的格式如下

C#中32位浮點(diǎn)數(shù)Float實(shí)例代碼分析

3、翻譯一下

(1)最高位是符號(hào)位,“0”代表正,“1”代表負(fù)。

(2)接下來的8位是指數(shù)位,8位可表示整數(shù)的范圍是0-255,考慮指數(shù)可以是負(fù)的,IEEE規(guī)定在上面的范圍減去127,并將-127(全0)和128(全1)用做特殊值處理,所以指數(shù)的位的范圍是(-127,128)。

(3)最低的23位是小數(shù)位(尾數(shù)位),正常是可以表示23位的范圍,但是IEEE規(guī)定小數(shù)點(diǎn)左側(cè)必須為1,右側(cè)位數(shù)不夠補(bǔ)0。這樣可以就可以省略1,可以用23位來表示24位。

eg. 1.111011101*2^6中,小數(shù)位是111011101+補(bǔ)14個(gè)0

4、定點(diǎn)轉(zhuǎn)浮點(diǎn)實(shí)例:123.625用32位浮點(diǎn)表示

科學(xué)計(jì)數(shù)法=1.111011101*26(整數(shù)部分:123=01111011b,小數(shù)部分:0.625=0.101b,整數(shù)部分除2取余,倒序排列,高位補(bǔ)零;小數(shù)部分乘2取整,順序排列)

符號(hào)位:0

指數(shù)位:6+127=10000101

小數(shù)位:11101110100000000000000

即:01000010111101110100000000000000=0x42F74000

5、驗(yàn)證

C#中32位浮點(diǎn)數(shù)Float實(shí)例代碼分析

6、浮點(diǎn)轉(zhuǎn)定點(diǎn)實(shí)例

42F74000=01000010111101110100000000000000,拆分為符號(hào)位、指數(shù)位、小數(shù)位。

(1)符號(hào)位:0

(2)指數(shù)位:10000101=133,實(shí)際指數(shù)=133-127=6

(3)小數(shù)位:11101110100000000000000去掉后面的0、前面補(bǔ)1為1. 111011101

即科學(xué)計(jì)數(shù)法表示為1. 111011101*26=(2^0+2^-1+2^-2+2^-3+2^-5+2^-6+2^-7+2^-9)*2^6=123.625。

到此,關(guān)于“C#中32位浮點(diǎn)數(shù)Float實(shí)例代碼分析”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

標(biāo)題名稱:C#中32位浮點(diǎn)數(shù)Float實(shí)例代碼分析
文章起源:http://www.muchs.cn/article12/gehdgc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)建站、搜索引擎優(yōu)化、做網(wǎng)站、網(wǎng)站改版、網(wǎng)站內(nèi)鏈、品牌網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)