【问题标题】:BitConverter.GetBytes() showing incorrect value?BitConverter.GetBytes() 显示不正确的值?
【发布时间】:2019-11-22 11:26:34
【问题描述】:

我正在尝试查看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

即。 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
        }
    }
}

【问题讨论】:

  • GetBytes 方法返回的数组中字节的顺序取决于计算机体系结构是 little-endian 还是 big-endian。

标签: c# math floating-point binary .net-4.7.2


【解决方案1】:

首先,你弄错了order of the parts。它是符号位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

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

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

【讨论】:

    猜你喜欢
    • 2023-03-23
    • 2019-06-18
    • 2020-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-30
    • 2019-02-22
    相关资源
    最近更新 更多