如何在c#中进行按位添加?

时间:2017-09-26 15:59:53

标签: c# types operators bit addition

我正在尝试编程PLC地址生成器。然而,我需要做一点点添加以找到下一个可用的地址。

这意味着如果我从地址0.0开始并添加2位,那么下一个免费地址将为0.3。它上升到0.7然后下一个地址是1.0到1.7然后是2.0,依此类推。

根据我添加到添加内容的数据类型,应计算下一个免费地址。

例如bool是一位。 0.1-> 0.2 - > 0.3等等 如果我添加一个字节,则字节有8位,最后一个空闲地址为0.4,下一个空闲地址应为2.0。

Word有16位,所以0.0 - > 2.0 - > 4.0等等。

双字有32位,所以0.0 - > 4.0 - > 8.0等等。

我在c#中寻找一个实现,我可以在其中添加不同的类型作为输入,然后添加它并为我提供相应的地址和存储,然后为下一个操作存储下一个空闲地址。

例如:

    Type         Startaddress
1   Bool         0.0            (->0.1)
2   Bool         0.1            (->0.2)
3   Byte         1.0            (->1.7) as 8 bits are required
4   Bool         2.0            (->2.1) 
5   Word         3.0            (->4.7) as 16 bits are required
6   Double Word  5.0            (->8.7) as 32 bits are required

我知道除了很多if else和循环之外我怎么能实现它?我正在寻找一种优雅的重载运算符方法。

4 个答案:

答案 0 :(得分:0)

您可以将这些地址存储在int中 - 前3位的下半部分,其余位在其余位中,并从那里获取地址。这允许您对这些地址和数字进行常规算术运算。如果地址在字符串中,您可以执行以下操作:

@app.route('/', methods=['GET', 'POST'])
@app.route('/index', methods=['GET', 'POST'])
@app.route('/index/<int:page>', methods=['GET', 'POST'])
@login_required
def index(page=1):
    form = PostForm()
    ...

答案 1 :(得分:0)

唯一的&#34;技巧&#34;对于你的问题,比特地址的符号为.0-.7,而C#类型与你的规范中的类型完全不匹配。

我在这里展示的主类在内部将地址存储为位偏移,并通过fAddress()方法提供整数和小数部分。

您的示例显示了字节边界上的对齐方式,但没有对齐单词或双字 - 这就是我实现的内容。评论显示如果PLC关心如何以不同的方式做到这一点。

您需要添加代码以在byte.bit类型的地址存储值。

using System;

namespace PLCAddress
{
    class Program
    {
        static void Main(string[] args)
        {
            PLCAddress a = new PLCAddress();
            float address;
            bool boolA = true;
            byte byteA = 7;
            ushort wordA = 65535;
            uint dblwordA = 4294967295;

            address = a.Store(boolA);
            Console.WriteLine(address.ToString());

            address = a.Store(boolA);
            Console.WriteLine(address.ToString());

            address = a.Store(byteA);
            Console.WriteLine(address.ToString());

            address = a.Store(boolA);
            Console.WriteLine(address.ToString());

            address = a.Store(wordA);
            Console.WriteLine(address.ToString());

            address = a.Store(dblwordA);
            Console.WriteLine(address.ToString());
        }
    }
    public class PLCAddress
    {
        protected uint _address;
        public PLCAddress()
        {
            _address = 0;
        }

        public float Store(bool b)
        {
            float rv = fAddress();
            _address += 1;
            return rv;
        }
        public float Store(byte b)
        {
            float rv = fAddress(8);
            _address += 8;
            return rv;
        }
        public float Store(ushort b)
        {
            float rv = fAddress(8); // use fAddress(16) if words need to be on word boundaries
            _address += 16;
            return rv;
        }
        public float Store(uint b)
        {
            float rv = fAddress(8); // use fAddress(32) if double words need to be on double word boundaries
            _address += 32;
            return rv;
        }

        protected float fAddress()
        {
            return (float)Whole + (float)Fraction / 10;
        }

        protected float fAddress(uint alignment)
        {
            uint roundup = alignment - 1;
            uint mask = ~roundup;
            uint AlignedAddress = _address + roundup;
            AlignedAddress = AlignedAddress & mask;
            _address = AlignedAddress;
            return fAddress();
        }
        protected uint Whole
        {
            get { return _address / 8; }
        }
        protected uint Fraction
        {
            get { return _address % 8;  }
        }
    }
}

答案 2 :(得分:0)

我个人更喜欢面向对象的方法:

public class MemoryManager
{
    private int _dataSize = 0;

    public enum DataTypes
    {
        Bool = 1,
        Byte = 8,
        Word = 16,
        DWord = 32
    }
    public MemoryLocation Add(DataTypes type)
    {            
        var address = GetCurrentAddress();
        _dataSize += (int)type;
        return address;
    }

    private MemoryLocation GetCurrentAddress()
    {
        int currentByteLocation = _dataSize / 8;
        int currentBitLocation = _dataSize % 8;            
        return new MemoryLocation(currentByteLocation, currentBitLocation);
    }        
}

public class MemoryLocation
{
    public MemoryLocation(int byteLocation, int bitIndex)
    {
        ByteLocation = byteLocation;
        BitIndex = bitIndex;            
    }
    public int ByteLocation { get; private set; }
    public int BitIndex { get; private set; }        
    public override string ToString()
    {
        return string.Format("[{0},{1}]", ByteLocation, BitIndex);
    }
}

我真的快速地推出了这个,但你可以使用其他更简化的方法来生成下一个地址。

答案 3 :(得分:0)

您可以使用:

public int BitWiseAdd()
{
            int FirstNumber = 50;
            int SecondNumber = 60;
            while (SecondNumber !=0)
            {

                int carry = FirstNumber & SecondNumber;
                FirstNumber = FirstNumber ^ SecondNumber;
                SecondNumber = carry << 1;
            }
            return FirstNumber;


}