首页 > 解决方案 > BitConverter.GetBytes() 显示不正确的值?

问题描述

我正在尝试查看System.Single值在内存中的表示方式。

从我读过的内容来看,System.Single它是这样表示的:

1 个符号位 (s)、23 位小数有效位 (f) 和 8 位偏置指数 (e)。

(-1)^s * 1.f * 2^(e-127)

在 16777216 的情况下,s = 0, f = 00000000000000000000000(23 个零),e = 151 = 10010111

IE。1.00000000000000000000000 * 2^24

在内存中,我希望它看起来像这样(符号位、小数有效数、有偏指数):

 0 00000000000000000000000 10010111

或以字节为单位:

00000000 00000000 00000000 10010111

但相反,它给了我这个:

00000000 00000000 10000000 01001011

看起来偏置指数中缺少最后一位,并且在第 3 个字节的开头随机出现 1,这是为什么呢?

通过反转每个字节中的位,我能够找到正确的指数:

00000000 00000000 00000001 11010010

取最后 9 位并再次反转它们:

00000000 00000000 0000000 010010111

现在这等于我的预期,但是这个奇怪的顺序是怎么回事?

这个二进制数以什么格式存储?

这是我的代码:

using System;
using System.Linq;

namespace SinglePrecision
{
    class Program
    {
        static void Main(string[] args)
        {
            Single a = 16777216;            
            byte[] aBytes = BitConverter.GetBytes(a);
            string s = string.Join(" ", aBytes.Select(x => Convert.ToString(x, 2).PadLeft(8, '0')));
            //s = 00000000 00000000 10000000 01001011
        }
    }
}

标签: c#mathfloating-pointbinary.net-4.7.2

解决方案


首先,你弄错了零件的顺序。它是符号位s,然后是指数e,然后是分数f,所以你的二进制表示,否则你计算正确,将是

0 10010111 00000000000000000000000
s e        f

这些位存储在 4 个连续字节的内存中:

01001011 10000000 00000000 00000000
se        f
byte1    byte2    byte3    byte4

但是因为您的系统是little-endian,所以它们以相反的顺序存储:

00000000 00000000 10000000 01001011
byte4    byte3    byte2    byte1

Endiannes 颠倒字节顺序,但不颠倒字节内的位顺序。

右边的字节是浮点值的第一个逻辑字节,最左边的位是符号位,即0.
右字节的第二个是第二个逻辑字节,它的最左位是指数的最后一位。


推荐阅读