Last active
July 21, 2023 02:16
-
-
Save Kittoes0124/e51576aa442d5dc7f1340e09d46fdc69 to your computer and use it in GitHub Desktop.
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
var decode = 4188287251U; // 4238739751U; // 4265539247U; | |
var encode = 4160962843U; // 4236695191U; // 2130976847U; | |
var sw = Stopwatch.StartNew(); | |
for (var i = 1U; i <= (uint.MaxValue / 2); i += 4) { | |
var ei0 = unchecked((i + 0) * encode); | |
var ei1 = unchecked((i + 1) * encode); | |
var ei2 = unchecked((i + 2) * encode); | |
var ei3 = unchecked((i + 3) * encode); | |
var ipi0 = IpAddressV4.New(value: ei0); | |
var ipi1 = IpAddressV4.New(value: ei1); | |
var ipi2 = IpAddressV4.New(value: ei2); | |
var ipi3 = IpAddressV4.New(value: ei3); | |
var ci0 = ipi0.ToCoordinates(); | |
var ci1 = ipi1.ToCoordinates(); | |
var ci2 = ipi2.ToCoordinates(); | |
var ci3 = ipi3.ToCoordinates(); | |
Console.WriteLine($"i: {(ei0 * decode).ToString().PadLeft(10, '0')} | ip: {ipi0, 15} | w: {ci0.W, 3}, x: {ci0.X, 3}, y: {ci0.Y, 3}, z: {ci0.Z, 3}"); | |
Console.WriteLine($"i: {(ei1 * decode).ToString().PadLeft(10, '0')} | ip: {ipi1, 15} | w: {ci1.W, 3}, x: {ci1.X, 3}, y: {ci1.Y, 3}, z: {ci1.Z, 3}"); | |
Console.WriteLine($"i: {(ei2 * decode).ToString().PadLeft(10, '0')} | ip: {ipi2, 15} | w: {ci2.W, 3}, x: {ci2.X, 3}, y: {ci2.Y, 3}, z: {ci2.Z, 3}"); | |
Console.WriteLine($"i: {(ei3 * decode).ToString().PadLeft(10, '0')} | ip: {ipi3, 15} | w: {ci3.W, 3}, x: {ci3.X, 3}, y: {ci3.Y, 3}, z: {ci3.Z, 3}"); | |
Console.ReadKey(intercept: true); | |
} | |
Console.WriteLine(sw.Elapsed.TotalSeconds); | |
readonly struct Coordinates4D<T> where T : IBinaryInteger<T> | |
{ | |
public static Coordinates4D<T> New(T w, T x, T y, T z) => | |
new(w: w, x: x, y: y, z: z); | |
public T W { get; init; } | |
public T X { get; init; } | |
public T Y { get; init; } | |
public T Z { get; init; } | |
private Coordinates4D(T w, T x, T y, T z) { | |
W = w; | |
X = x; | |
Y = y; | |
Z = z; | |
} | |
} | |
readonly struct IpAddressV4 | |
{ | |
public static IpAddressV4 New(uint value) => | |
new(value: value); | |
public static IpAddressV4 operator +(IpAddressV4 value, uint other) => New(value: (value.Value + other)); | |
public static IpAddressV4 operator ++(IpAddressV4 value) => (value + 1U); | |
public static IpAddressV4 operator -(IpAddressV4 value, uint other) => New(value: (value.Value - other)); | |
public static IpAddressV4 operator --(IpAddressV4 value) => (value - 1U); | |
public uint Value { get; init; } | |
private IpAddressV4(uint value) { | |
Value = value; | |
} | |
public Coordinates4D<byte> ToCoordinates() { | |
var (l, r) = Value.ElegantUnpair<uint, ushort>(); | |
var (w, x) = l.ElegantUnpair<ushort, byte>(); | |
var (y, z) = r.ElegantUnpair<ushort, byte>(); | |
return Coordinates4D<byte>.New(w: w, x: x, y: y, z: z); | |
} | |
public override string ToString() { | |
var buffer = (stackalloc char[16]); | |
var length = FormatValue( | |
buffer: buffer, | |
value: (BitConverter.IsLittleEndian ? BinaryPrimitives.ReverseEndianness(value: Value) : Value) | |
); | |
return new(buffer[..length]); | |
static int FormatValue<TChar>(Span<TChar> buffer, uint value) where TChar : unmanaged, IBinaryInteger<TChar> { | |
var index = FormatByte(buffer: buffer, ones: (value >> 24)); | |
buffer[index++] = TChar.CreateTruncating(value: '.'); | |
index += FormatByte(buffer: buffer[index..], ones: (value >> 16)); | |
buffer[index++] = TChar.CreateTruncating(value: '.'); | |
index += FormatByte(buffer: buffer[index..], ones: (value >> 8)); | |
buffer[index++] = TChar.CreateTruncating(value: '.'); | |
index += FormatByte(buffer: buffer[index..], ones: value); | |
return index; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static int FormatByte(Span<TChar> buffer, uint ones) { | |
ones &= 0xFF; | |
if (ones >= 10) { | |
if (ones >= 100) { | |
(var hundredsAndTens, ones) = Math.DivRem(left: ones, right: 10); | |
(var hundreds, var tens) = Math.DivRem(left: hundredsAndTens, right: 10); | |
buffer[2] = TChar.CreateTruncating(value: ('0' + ones)); | |
buffer[1] = TChar.CreateTruncating(value: ('0' + tens)); | |
buffer[0] = TChar.CreateTruncating(value: ('0' + hundreds)); | |
return 3; | |
} | |
else { | |
(var tens, ones) = Math.DivRem(left: ones, right: 10); | |
buffer[1] = TChar.CreateTruncating(value: ('0' + ones)); | |
buffer[0] = TChar.CreateTruncating(value: ('0' + tens)); | |
return 2; | |
} | |
} | |
else { | |
buffer[0] = TChar.CreateTruncating(value: ('0' + ones)); | |
return 1; | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment