【问题标题】:How can I encode two numbers in a single Integer?如何在一个整数中编码两个数字?
【发布时间】:2012-07-11 19:15:27
【问题描述】:

我需要存储一系列值(如 25-50 或 100-200),但是为了避免大量的数据库重新设计和其他工作,我想使用单个 Int32 来存储两者这些数字。我意识到每个数字只有 16 位,但这很好。

因此,使用两个整数值非常容易。我可以这样做:

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));

现在,我有右 16 位存储值 50,左 16 位存储值 25。

那么问题是什么?

现在,我想使用相同的技术,但我想存储两个非整数。例如,1.5 和 1.75,或 2.00 和 2.25。 .NET 似乎不支持floatsingledoubledecimal 上的位移运算符。 另外,我最终还需要在 Javascript 中读取这些值,因此怀疑使用的任何位编码浮点是否在平台之间完全兼容。

最好的方法是什么?我正在考虑的一种方法是仅使用整数,但将所有内容除以 1000。这将使我在两个数字中都有 3 个小数点精度,尽管我必须将整个内容存储为 long 以存储超过 65 的任何内容。我不确定这是否是最好的方法。也许我缺少一些简单的东西。

【问题讨论】:

  • 您缺少的一些简单的东西可能是更改您的数据库架构。
  • 最好的方法是继续往数据库中添加适当的列。上帝帮助下一个必须处理这个黑客的可怜人。
  • 我认为这就是人们所说的technical debt。而且,如果您使用 hack 而不是仅仅纠正设计问题,那么您只是在推迟偿还该债务(其一直在以复利增长)。每次 hack 都会使问题更加复杂,因此最终唯一的选择是完全重写,这将花费更多的时间/金钱。
  • @Lèsemajesté - 最后,你的评论让我反对这个想法。我决定停止尝试将圆形钉子安装到方孔中,而是重新钻孔以正确安装钉子。花了大约 2 天的时间,但由于它,现在的设计更优越。我认为这仍然是一个不错的问题,因为有人可能有正当理由将两个浮点数编码为一个 int。
  • @Mike:这一个合理的问题。而且我认为即使是黑客攻击,它仍然是不可避免的(例如,你花了 2 天时间来完成重新设计,但一个不可协商的截止日期可能是 1 天之后)。这就是为什么所有软件项目都有技术债务,而且并不总是由于无能。但重要的是要认识到,您正在累积债务,而且未偿还的时间越长。因为实际上需要一个非常有纪律的开发人员/团队才能真正安排定期分配的时间来在截止日期前偿还技术债务。

标签: c# javascript .net floating-point bitmask


【解决方案1】:

一点数学就可以解决这个问题。

首先确定你的精度,比如 2 位数字,你的数字范围直到 1000

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

前 4 位是 num1,然后是 num2。

你可以让他们逆转这个过程。

【讨论】:

  • 我认为这也是我会采用的方法,特别是因为它完全兼容 Javascript。如果我决定走这条路。没想到这个问题会引起这么大的争议!
  • 这将很难维护,想象一下如果您明天必须在其中一个列上进行搜索。有时这种方法确实有意义,例如将多个变量打包成一个以节省传输字节。记录好黑客攻击,这样下一个人就不会傻眼了。
【解决方案2】:

只要您没有很多小数位,最简单的解决方案就是将每个数字与您想要的小数位数相乘,然后将两个数字转换为整数,执行位运算,然后将结果存储在数据库中。

阅读它们时,您只需将数字拆分,然后除以您之前使用的因子。

【讨论】:

    【解决方案3】:

    您所问的在数学中称为“配对函数”。

    配对函数有很多,其中有Goedel's、Cantor's等。

    哥德尔 p.f.对嵌套语言进行编码是不切实际的,但对于符号不多的普通语言来说非常好。

    【讨论】:

      【解决方案4】:

      在 C# 中,您有 BitConverter。您可以在代码中将 DB 中的 Float 值转换为字节数组,然后对它执行任何您需要的操作,然后将其转换回 Float,然后再将其保存到 DB。

      请参阅下面的帖子以获取示例。

      C#: Convert Byte array into a float

      【讨论】:

      • 在不知道如何将其缩短为 16 位的情况下切割位是行不通的。花车有点奇怪。
      【解决方案5】:

      您可以使用 float 到 byte[] 的转换从答案到this question

      当你有一个字节数组时,你可以使用你的掩码技术。

      【讨论】:

      • 但是屏蔽适用于字节数组!将浮点数转换为 byte[] 然后进行屏蔽!
      • 但是你将如何恢复它并获得完全相同的浮动?
      • 点击我回答中的链接。在该问题的答案中,您还将找到用于 byte[]-to-float 和 float-to-byte[] 转换的方法。
      • 你打算怎么打包两个byte[4]的一个Int32/Uint32/byte[4]
      猜你喜欢
      • 1970-01-01
      • 2019-10-24
      • 2017-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-20
      • 2018-12-11
      • 2020-01-07
      • 2011-11-19
      相关资源
      最近更新 更多