-
-
Save orange-in-space/e0e824e5ae79d3196df9b20a174d5c9a to your computer and use it in GitHub Desktop.
一応ちゃんと動く気がする、2~63bitの任意の長さのbit長のSigned/Unsignedの整数になる可変的な整数型っぽいもの><
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
//CC0 (C)orange_in_space | |
namespace orange.FlexBitInteger | |
{ | |
public interface IFlexInt | |
{ | |
bool Signed { get; } | |
int BitLength { get; } | |
long Max { get; } | |
long Min { get; } | |
byte[] GetBytes(); | |
} | |
public class FlexibleBitLengthInteger : IFlexInt | |
{ | |
private long abs_value = 0; | |
private int v_sign = 1; | |
private long v_bitmask = 0; | |
public bool Signed { get; } = false; | |
public int BitLength { get; } = 0; | |
public long Max { get; } = 0; | |
public long Min { get; } = 0; | |
private static long CreateBitmask(int bitLength) | |
{ | |
return ((long)1 << bitLength) - 1; | |
} | |
public FlexibleBitLengthInteger(long long_value, int bitLength, bool signed = true) | |
{ | |
Signed = signed; | |
if ((bitLength < 2) || (bitLength > 63)) | |
{ | |
throw new ArgumentOutOfRangeException(); | |
} | |
BitLength = bitLength; | |
if (Signed) | |
{ | |
Min = -((long)1 << (BitLength - 1)); | |
Max = ((long)1 << (BitLength - 1)) - 1; | |
v_bitmask = CreateBitmask(bitLength - 1); | |
} | |
else | |
{ | |
Min = 0; | |
Max = ((long)1 << BitLength) - 1; | |
v_bitmask = CreateBitmask(bitLength); | |
} | |
SetFromInt64(long_value); | |
} | |
public void SetFromInt64(long value) | |
{ | |
if (Signed) | |
{ | |
abs_value = Math.Abs(value) & v_bitmask; | |
v_sign = Math.Sign(value); | |
} | |
else | |
{ | |
abs_value = Math.Abs(value) & v_bitmask; | |
v_sign = 1; | |
} | |
} | |
public static explicit operator long(FlexibleBitLengthInteger value) | |
{ | |
return value.abs_value * value.v_sign; | |
} | |
public static explicit operator byte[] (FlexibleBitLengthInteger value) | |
{ | |
long longValue = ((long)value) & CreateBitmask(value.BitLength); | |
byte[] result = BitConverter.GetBytes(longValue); | |
return result; | |
} | |
public byte[] GetBytes() | |
{ | |
return (byte[])this; | |
} | |
public override string ToString() | |
{ | |
return ((long)this).ToString(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment