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

标签 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。

一个单词有 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 和循环之外,我知道如何实现它吗?我正在寻找一种优雅的重载运算符方法。

最佳答案

您的问题的唯一“技巧”是位地址的 .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;  }
        }
    }
}

关于c# - 如何在c#中进行按位相加?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46431063/

相关文章:

javascript - 如何在 Jint 中使用下划线函数

c# - 给 CIL 写评论

c# - 使用具有行限制的数据适配器填充数据集

c++ - 返回对重载私有(private) & 运算符的类的引用?

operators - 是否可以在 Raku 中定义自定义元操作符?

c++ - C++中运算符和函数的区别?

c# - Entity Framework 和整词匹配——分页和过滤结果

types - 设计类图时图像的数据类型是什么?

types - 在定义它们的模块之外使用开放联合

haskell - 在 Haskell 中创建泛型函数类型的集合有用吗