diff --git a/csharp/Platform.Data.Doublets/Converters/AddressToUnaryNumberConverter.cs b/csharp/Platform.Data.Doublets/Converters/AddressToUnaryNumberConverter.cs new file mode 100644 index 000000000..f10eb617f --- /dev/null +++ b/csharp/Platform.Data.Doublets/Converters/AddressToUnaryNumberConverter.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using System.Numerics; +using Platform.Interfaces; +using Platform.Reflection; +using Platform.Numbers; + +namespace Platform.Data.Doublets.Converters +{ + public class AddressToUnaryNumberConverter : LinksOperatorBase, IConverter where TLink : IUnsignedNumber + { + private static readonly EqualityComparer _equalityComparer = EqualityComparer.Default; + + private readonly IConverter _powerOf2ToUnaryNumberConverter; + + public AddressToUnaryNumberConverter(ILinks links, IConverter powerOf2ToUnaryNumberConverter) : base(links) => _powerOf2ToUnaryNumberConverter = powerOf2ToUnaryNumberConverter; + + public TLink Convert(TLink sourceAddress) + { + var number = sourceAddress; + var target = Links.Constants.Null; + for (int i = 0; i < CachedTypeInfo.BitsLength; i++) + { + if (_equalityComparer.Equals(ArithmeticHelpers.And(number, Integer.One), Integer.One)) + { + target = _equalityComparer.Equals(target, Links.Constants.Null) + ? _powerOf2ToUnaryNumberConverter.Convert((sbyte)i) + : Links.GetOrCreate(_powerOf2ToUnaryNumberConverter.Convert((sbyte)i), target); + } + number = (Integer)((ulong)(Integer)number >> 1); // Should be BitwiseHelpers.ShiftRight(number, 1); + if (_equalityComparer.Equals(number, default)) + { + break; + } + } + return target; + } + } +} \ No newline at end of file