-1

i have array of byte, i want to find 32-bit unsigned fixed-point number (16.16) ) use c# and

the output must 44100

array of byte:

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

The output is 17580. This is wrong: it should be 44100

how to convert it to (a 32-bit unsigned fixed-point number (16.16) ) use c# ??

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194

2 Answers2

2

.Net doesn't have a built-in 32-bit fixed point data type, but you could store the result pretty easily in a double.

This is not quite as efficient or elegant as what you're probably looking for, but you could do something like this to convert your byte array to a 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

Alternatively, if you change the way you store the bits like this:

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

The conversion between your original storage format and this one is fairly straightforward. You could probably simply reverse the bytes, although I'm not entirely sure which decimal digit is more significant.

p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
  • @user2839704 That's 2¹⁶—i.e. `65536 == Math.Pow(2, 16)` – p.s.w.g Oct 14 '13 at 20:42
  • 1
    Why would you store in a double? Surely this is a strict with two ushort members? – David Heffernan Oct 14 '13 at 20:52
  • @userp.s.w.g why use 65536 in division – user2839704 Oct 14 '13 at 20:59
  • @DavidHeffernan Sure that could be done, but OP didn't ask for how to write a custom numeric type. As it stands the question is pretty unclear about what exactly the requirements are. See [this answer](http://stackoverflow.com/a/616015/1715579) for an example of how to do that. – p.s.w.g Oct 14 '13 at 21:02
  • @user2839704 because he is converting to Uint32 and then has to make sure it is a UInt16 `0xFFFFFFFF / 0x0001000 = 0xFFFF` 0xFFFF = 65535 add 1 and you get 0x10000 or 65536 – Harrison Oct 14 '13 at 21:03
  • @user2839704 Think of it this way... each byte has a certain significance. The first byte is 256 times *more* significant as the second byte. Similarly, the third byte is 256 times *less* significant than the second, and the fourth byte is 256 times *less* significant than the third. So `256 * 256 = 65536`. – p.s.w.g Oct 14 '13 at 21:09
  • Or the same with no `Zip`, I mean `double i = 256.0 * m[0] + m[1] + m[2] / 256.0 + m[3] / 65536.0;`. – Jeppe Stig Nielsen Oct 14 '13 at 21:24
0

Depending on how you answer @JonSkeet comment above will depend on the fractional value of this. However, this solution works for the integer part

        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));
Community
  • 1
  • 1
Harrison
  • 3,843
  • 7
  • 22
  • 49