C#中将32位二进制转换为float【Real】十进制类型

已知一个32位二进制字符串,转换为float【Real】十进制。

参考本人一篇博客 float数转二进制

C#关于32位浮点数Float(Real)一步步按位Bit进行解析_real32位浮点数_斯内科的博客-CSDN博客

 现在是32位二进制转化为十进制浮点数,C#有直接转换的方法类BitConverter:

使用四个字节【32位二进制】数组即可转化为一个float【Real】数字,代码如下:

float number = BitConverter.ToSingle(new byte[] { 12, 34, 56, 78 }, 0);

IEEE基础知识:

浮点数的32位N=1符号位(Sign)+8指数位(Exponent)+23尾数部分(Mantissa)

符号位(Sign) : 0代表正,1代表为负【占1位】
指数位(Exponent)::用于存储科学计数法中的指数数据,并且采用移位存储【占8位】
尾数部分(Mantissa):尾数部分【占23位】
单精度float:N共32位,其中S占1位,E占8位,M占23位。因此小数点后最多精确到23/4=6位 。

IEEE规则:二进制32位转换为float【Real】规则


第一位为1代表负数,第一位为0代表正数或者0
第二位到第九位代表 指数位,对应的值减去127就是移位数【shiftCount】
【第十位开始】尾数23位前面加一个1,凑够24位,这个24位尾数的前【shiftCount+1】个数就是整数部分,剩下的就是小数部分

整数二进制转为10进制:从低位到高位分别是2的0次幂、1次幂、2次幂……,分别相乘再相加,得到的和即为10进制结果。

小数部分的二进制转换位10进制:与整数部分类似,从小数点开始分别是2的-1次幂、-2次幂、-3次幂……,分别相乘再相加,得到的和即为10进制结果

扫描二维码关注公众号,回复: 15953156 查看本文章

因为C#是低字节在前的【BitConverter.IsLittleEndian为True】,我们需将四个字节 倒置

新建控制台应用程序:BinaryToFloatDemo,测试源程序如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BinaryToFloatDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.SetWindowSize(160, 20);
            //单精度浮点数对应32位
            //符号位(Sign) : 0代表正,1代表为负【占1位】
            //指数位(Exponent):用于存储科学计数法中的指数数据,并且采用移位存储【占8位】
            //尾数部分(Mantissa):尾数部分【占23位】
            //单精度float:N共32位,其中S占1位,E占8位,M占23位。因此小数点后最多精确到23/4=6位 
            //双精度double:N共32位,其中S占1位,E占11位,M占52位。因此小数点后最多精确到52/4=13位 

            //IEEE规则:二进制32位转float【Real】规则
            //第一位为1代表负数,第一位为0代表正数或者0
            //第二位到第九位代表 指数位,对应的值减去127就是移位数【shiftCount】
            //【第十位开始】尾数23位前面加一个1,凑够24位,这个24位尾数的前【shiftCount+1】个数就是整数部分,剩下的就是小数部分

            //整数二进制转为10进制:从低位到高位分别是2的0次幂、1次幂、2次幂……,分别相乘再相加,得到的和即为10进制结果。
            //小数部分的二进制转换位10进制:与整数部分类似,从小数点开始分别是2的-1次幂、-2次幂、-3次幂……,分别相乘再相加,得到的和即为10进制结果,比如001(2进制)对应0.125(10进制)
            
            byte[] binaryArraySource = new byte[4] { 80, 32, 241, 71 };
            byte[] binaryArray = binaryArraySource.Reverse().ToArray();
            Console.WriteLine($"将数组顺序反转,反转后为【{string.Join(",", binaryArray)}】");
            IEnumerable<string> binaryCollection = binaryArray.Select(element => Convert.ToString(element, 2).PadLeft(8, '0'));
            string binaryString = string.Join("", binaryCollection);
            Console.WriteLine($"转化为32位二进制,为【{string.Join("\x20", binaryCollection)}】");
            string signString = (binaryString[0] == '1' ? "-" : "+");
            Console.WriteLine($"符号位占用1位,为【{signString}】");
            string exponent = binaryString.Substring(1, 8);
            int shiftCount = Convert.ToByte(exponent, 2) - 127;
            Console.WriteLine($"指数位为8位【{exponent}】,对应数字【{Convert.ToByte(exponent, 2)}】,共移动【{shiftCount}】位");
            string mantissa = binaryString.Substring(9);
            string dotString = $"1.{mantissa}";
            Console.WriteLine($"尾数位为23位【{mantissa}】,尾数位前面添加一个1并插入移位小数点,字符串为【{dotString}乘以2的{shiftCount}次方】");
            dotString = dotString.Replace(".", "").Insert(shiftCount+1, ".");
            Console.WriteLine($"即【{dotString}】");
            string integerPart = dotString.Substring(0, shiftCount + 1);//整数部分
            string fractionalPart = dotString.Substring(shiftCount + 2);//小数部分

            //整数部分:从低位到高位 依次是2的0次方,2个1次方,2的2次方,然后累加
            int numberInteger = 0;
            for (int i = 0; i < integerPart.Length; i++)
            {
                if (integerPart[i] == '1') 
                {
                    numberInteger += (1 << (integerPart.Length - 1 - i));
                }
            }
            //小数部分:从小数点开始分别是2的-1次幂、-2次幂、-3次幂……
            double numberFractional = 0D;
            for (int i = 0; i < fractionalPart.Length; i++)
            {
                if (fractionalPart[i] == '1')
                {
                    numberFractional += Math.Pow(2, -1 - i);
                }
            }
            Console.WriteLine($"整数部分【{integerPart}】,对应整数字【{numberInteger}】.或者使用Convert,整数也为【{Convert.ToInt32(integerPart, 2)}】");
            Console.WriteLine($"小数部分【{fractionalPart}】,对应小数【{numberFractional}】");
            string destNumber = $"{signString}{numberInteger + numberFractional}";
            Console.WriteLine($"32位二进制对应的浮点数为【{destNumber}】,使用BitConverter转换为浮点数的结果为【{BitConverter.ToSingle(binaryArraySource, 0)}】");
            
            Console.ReadLine(); 
        }
    }
}

测试如图:

【注意:浮点数有精度限制】

猜你喜欢

转载自blog.csdn.net/ylq1045/article/details/130701458
今日推荐