最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - How can I encode two numbers in a single Integer? - Stack Overflow

programmeradmin5浏览0评论

I have the need to store a range of values (like 25-50 or 100-200), however to avoid a lot of database re-design and other work, I want to use a single Int32 to store both these numbers. I realize that I would only then have 16 bits for each number, but that's fine.

So, with two integer values this is pretty easy. I can do something like:

int mask = 50; //Right bits will have 50
mask |= (25 << 16); //Left bits will have 25

Console.WriteLine("Mask is: {0}", mask);
Console.WriteLine("Left is: {0}", (mask >> 16));
Console.WriteLine("Right is: {0}", (mask & 0xFFFF));

Now, I have the right 16 bits storing the value 50, and the left 16 bits storing the value 25.

So what's the question?

Now, I want to use the same technique but I want to store two non-integers. For example, 1.5 and 1.75, or 2.00 and 2.25. .NET doesn't seem to support bit shift operators on float, single, double or decimal. Plus, I need to also read these values eventually in Javascript so it's doubtful whatever bit encoding floating points use would be pletely patible between platforms.

What's the best way to do this? One approach I'm considering is just using integers, but dividing everything by 1000. That would give me 3 decimal point precision in both numbers, though I'd have to store the whole thing as a long to store anything over 65. I'm not sure if this is the best approach though. Maybe there's something easy I'm missing.

I have the need to store a range of values (like 25-50 or 100-200), however to avoid a lot of database re-design and other work, I want to use a single Int32 to store both these numbers. I realize that I would only then have 16 bits for each number, but that's fine.

So, with two integer values this is pretty easy. I can do something like:

int mask = 50; //Right bits will have 50
mask |= (25 << 16); //Left bits will have 25

Console.WriteLine("Mask is: {0}", mask);
Console.WriteLine("Left is: {0}", (mask >> 16));
Console.WriteLine("Right is: {0}", (mask & 0xFFFF));

Now, I have the right 16 bits storing the value 50, and the left 16 bits storing the value 25.

So what's the question?

Now, I want to use the same technique but I want to store two non-integers. For example, 1.5 and 1.75, or 2.00 and 2.25. .NET doesn't seem to support bit shift operators on float, single, double or decimal. Plus, I need to also read these values eventually in Javascript so it's doubtful whatever bit encoding floating points use would be pletely patible between platforms.

What's the best way to do this? One approach I'm considering is just using integers, but dividing everything by 1000. That would give me 3 decimal point precision in both numbers, though I'd have to store the whole thing as a long to store anything over 65. I'm not sure if this is the best approach though. Maybe there's something easy I'm missing.

Share Improve this question asked Jul 11, 2012 at 19:15 Mike ChristensenMike Christensen 91.7k51 gold badges219 silver badges347 bronze badges 6
  • 7 The something easy you're missing might be changing your database schema. – James M Commented Jul 11, 2012 at 19:17
  • 16 the best way is to go ahead and add the appropriate columns to the database. god help the next poor guy who has to deal with this hack. – Randy Commented Jul 11, 2012 at 19:17
  • 7 I think that's what people call technical debt. And if you go with the hack instead of just correcting the design problem, you're just putting off the repayment of that debt (which is growing with pound interest all the while). Each hack is pounding the problem even more, so that eventually the only option is a plete rewrite, which will cost even more time/money. – Lèse majesté Commented Jul 11, 2012 at 19:26
  • 1 @Lèsemajesté - In the end, your ment swayed me against this idea. I decided to stop trying to fit a round peg into a square hole, and instead just re-drill the hole to fit the peg correctly. It took about 2 days, but the design is now superior because of it. I think it's still a decent question though, as someone out there might have a legitimate reason to encode two floating points in a single int. – Mike Christensen Commented Jul 14, 2012 at 20:04
  • 1 @Mike: It is a legitimate question. And I think even in cases where it's a hack, it might still be unavoidable (e.g. it took you 2 days to plete the redesign, but a non-negotiable deadline could have been 1 day away). That's why all software projects have technical debt, and not always due to inpetence. But it's just important to recognize that you are accruing a debt that grows the longer it's unpaid. Because it takes a very disciplined developer/team to actually schedule regularly allotted time to repay that technical debt after the deadline has been met. – Lèse majesté Commented Jul 14, 2012 at 20:46
 |  Show 1 more ment

5 Answers 5

Reset to default 7

A little math could solve that.

First fix your precision, say 2 digits and your numbers range till 1000

both = Math.Round(num1, 2) * 10000 + Math.Round(num2, 2);

First 4 digits are for num1 and then you have num2.

You can get them back reversing the process.

As long as you do not have lots of decimal digits the easiest solution would be multiplying each number with whatever amount of decimals you want, then converting both numbers to ints, performing your bit operations and then storing the result in your database.

When reading them you simply split the number and then divide it by the factor you used before.

What you are asking is called in mathematics pairing function.

There are many pairing functions, amoung which there are Goedel's, Cantor's, etc.

Godel p.f. is not practical to encode nested languages, but it's excellent for plain languages with not so many symbols.

In C# you have BitConverter. You can convert the Float value from the DB to a byte array in code, then do whatever you need with it, then convert it back to Float before saving it to the DB.

See the post below for an example.

C#: Convert Byte array into a float

You can use the float to byte[] conversion from the answer to this question.

When you have a byte-array, you can use your masking technique.

发布评论

评论列表(0)

  1. 暂无评论