【问题标题】:A 32-bit unsigned fixed-point number (16.16)一个 32 位无符号定点数 (16.16)
【发布时间】:2013-10-15 04:41:17
【问题描述】:

我有字节数组,我想找到 32 位无符号定点数(16.16))使用 c# 和

输出必须是 44100

字节数组:

byte[] m = new byte[4] {172,68,0,0}
Console.WriteLine(" sample rate {0}", BitConverter.ToInt32(m, 0));

输出是 17580。这是错误的:应该是 44100

如何使用 c# 将其转换为(一个 32 位无符号定点数 (16.16) )??

【问题讨论】:

  • 输出必须是44100。输入是什么?
  • 您是否期望得到非整数值,或者最后两个字节总是为 0?如果要处理非整数值,可以举个例子吗?
  • 您的输入似乎是 Big Endian 顺序(当然,如果您有一个 16.16 的定点数,则不能这样打印)
  • 44100 = 0xAC44。 172 = 0xAC,68 = 0x44。
  • 使用 BitConverter.ToInt32(m, 0) 代替 BitConverter.ToUInt32(m, 0) 的任何原因?

标签: c#


【解决方案1】:

.Net 没有内置的 32 位定点数据类型,但您可以很容易地将结果存储在 double 中。

这并不像您可能正在寻找的那样高效或优雅,但是您可以执行以下操作将字节数组转换为双精度:

byte[] m = new byte[4] { 172, 68, 0, 0 };
double[] magnitude = new[] { 256.0, 1.0, 1.0/256.0, 1.0/65536.0 };
double i = m.Zip(magnitude, (x, y) => x * y).Sum(); // 44100.0

或者,如果您更改存储位的方式,如下所示:

byte[] m = new byte[4] { 0, 0, 68, 172 };
double i = BitConverter.ToUInt32(m, 0) / 65536.0;   // 44100.0

原始存储格式与此格式之间的转换相当简单。您可能可以简单地反转字节,尽管我不完全确定哪个十进制数字更重要。

【讨论】:

  • @user2839704 那是 2¹⁶——即65536 == Math.Pow(2, 16)
  • 你为什么要存储在一个double中?这肯定是对两个 ushort 成员的严格要求吗?
  • @userp.s.w.g 为什么在除法中使用 65536
  • @DavidHeffernan 当然可以,但是 OP 没有询问如何编写自定义数字类型。就目前而言,这个问题还不清楚具体的要求是什么。有关如何执行此操作的示例,请参阅 this answer
  • @user2839704 因为他正在转换为 Uint32,然后必须确保它是 UInt16 0xFFFFFFFF / 0x0001000 = 0xFFFF 0xFFFF = 65535 加 1 得到 0x10000 或 65536
【解决方案2】:

取决于你如何回答@JonSkeet 上面的评论将取决于它的小数值。但是,此解决方案适用于整数部分

        byte[] m = new byte[4] { 172, 68, 0, 0 };
        byte[] fraction = m.Reverse().Take(2).ToArray();
        byte[] integer = m.Reverse().Skip(2).Take(2).ToArray();

        System.Diagnostics.Debug.Print("{0}", BitConverter.ToUInt16(integer, 0));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 2012-05-24
    • 2011-01-17
    • 2021-12-27
    • 2019-10-31
    • 1970-01-01
    • 2012-07-27
    相关资源
    最近更新 更多