代码之家  ›  专栏  ›  技术社区  ›  Ego Placebo

标识BitValue列中的值

  •  1
  • Ego Placebo  · 技术社区  · 7 年前

    注意:我不知道如何最好地标题和标签这个问题,所以欢迎有用的编辑!

    我正在逆向工程ASP。NET Webforms网站(我没有正确版本的源代码)到ASP。NET MVC使用数据库优先实体框架,我很难理解特定视图/数据集是如何工作的。

    一条记录有一个“选项”字段,其中包含一系列数字,读取这些数字时,可以识别48个选项中的哪一个是正确的。我正试图弄清楚如何读/写这个结果。

    因此,选项表的结构如下: enter image description here 如您所见,有一个BitValue列(一直到281474976710656);我相信这就是我需要用来识别选项的地方,当出现这样的数字时:5120或17592186044480 如果这个数字只确定了一个选项,我可能可以更容易地解决这个问题,但不幸的是,可以确定几个选项。

    例如,记录的选项字段中有以下内容:17592186044480 此标识的选项(当我参考现有网站时)包括: 过程(位值:64) 岸上船员错误(位值:17592186044416)

    但我一辈子都搞不清楚这两个数字如何转化为选项字段中的数字!

    有什么提示吗?

    好的,那么64+17592186044416=17592186044480,这有助于理解数字是如何生成的,但是我如何反转它来识别组成数字的选项呢?

    结论 我接受了一个答案,因为它结合了一些评论,帮助我找到了解决方案。

    最后,我把“选项”写成一个枚举,就像这样。。。

    [Flags] public enum options : long
    {
        Master_Pilot_Exchange = 2,
        Bridge_Team_Issues = 4,
        Language_Difficulty = 8,
        Briefing = 16,
        Crew_Competency = 32,
        Procedure = 64,
        Personal_Performance = 128,
        Fatigue = 256,
        ....
    }
    

    并创建了一个函数来检查每个选项,以查看其是否包含在bitValue中:

    private bool checkBits(long maskIn, int optionId)
        {
            options mask = (options)maskIn;
            var toCheck = db.InitialReportOptions.Single(i => i.InitialReportOptionID == optionId);
            options chk = (options)toCheck.BitValue;
            bool test = false;
            if ((mask & chk) == chk)
            {
                test = true;
            }
            //
            return test;
        }
    

    当我需要向记录中添加新的位值时,我会使用以下方法:

    options newMask = (options)0;
                long bitResult = 0;
                foreach(var option in model.ReportOptions)
                {
                    if (option.IsTrue)
                    {
                        var bitv = (options)option.BitValue;
                        bitResult = bitResult | ( (long)newMask | (long)bitv);
                    }
                }
                model.InitialReportRecord.Options = bitResult;
    

    我敢说这可能会更有效率,但它很有效,所以我很高兴!

    1 回复  |  直到 7 年前
        1
  •  2
  •   Mick    7 年前

    首先,您需要知道48个标志中每个标志的位值。。。。然后在C#。。。

    const int Procedure = 64
    
    if ((myData.InitialReportOption & Procedure) == Procedure)
       // Then Procedure flag is active
    else  // (myData.InitialReportOption & Procedure) == 0
       // Procedure is not active
    

    同样,为了使您能够。。。

    myData.InitialReportOption |= Procedure;
    

    和禁用

    myData.InitialReportOption &= ~Procedure;
    

    有关详细信息,请尝试此博客。。。

    http://blog.typps.com/2007/10/bitwise-operators-in-c-or-xor-and-not.html