Matching oolong to long in C #?

I am trying to map ulong to long (and vice versa) and uint to int (and vice versa) as shown below - in order to store values ​​in an MS-SQL database with signed types only integer and large integer.

I do this because I have to check (in the database) whether the number (uint, ulong) is within what range in the range of uint / ulong ranges (IP addresses are v4 and v6; actually ulong actually represents itself uint128, consisting of two oolongs).

UlongToLong

UIntToInt

Is there a more efficient way to do this than the code I'm here:

public static ulong SignedLongToUnsignedLong(long signedLongValue) { ulong backConverted = 0; // map ulong to long [ 9223372036854775808 = abs(long.MinValue) ] if (signedLongValue < 0) { // Cannot take abs from MinValue backConverted = (ulong)System.Math.Abs(signedLongValue - 1); backConverted = 9223372036854775808 - backConverted - 1; } else { backConverted = (ulong)signedLongValue; backConverted += 9223372036854775808; } return backConverted; } public static long UnsignedLongToSignedLong(ulong unsignedLongValue) { // map ulong to long [ 9223372036854775808 = abs(long.MinValue) ] return (long) (unsignedLongValue - 9223372036854775808); } public static int UnsignedIntToSignedInt(uint unsignedIntValue) { // map uint to int [ 2147483648 = abs(long.MinValue) ] return (int)(unsignedIntValue - 2147483648); } public static uint SignedIntToUnsignedInt(int signedIntValue) { uint backConverted = 0; // map ulong to long [ 2147483648 = abs(long.MinValue) ] if (signedIntValue < 0) { // Cannot take abs from MinValue backConverted = (uint)System.Math.Abs(signedIntValue - 1); backConverted = 2147483648 - backConverted - 1; } else { backConverted = (uint)signedIntValue; backConverted += 2147483648; } return backConverted; } public static void TestLong() { long min_long = -9223372036854775808; long max_long = 9223372036854775807; ulong min_ulong = ulong.MinValue; // 0 ulong max_ulong = ulong.MaxValue; // 18446744073709551615 = (2^64)-1 long dbValueMin = UnsignedLongToSignedLong(min_ulong); long dbValueMax = UnsignedLongToSignedLong(max_ulong); ulong valueFromDbMin = SignedLongToUnsignedLong(dbValueMin); ulong valueFromDbMax = SignedLongToUnsignedLong(dbValueMax); System.Console.WriteLine(dbValueMin); System.Console.WriteLine(dbValueMax); System.Console.WriteLine(valueFromDbMin); System.Console.WriteLine(valueFromDbMax); } public static void TestInt() { int min_int = -2147483648; // int.MinValue int max_int = 2147483647; // int.MaxValue uint min_uint= uint.MinValue; // 0 uint max_uint = uint.MaxValue; // 4294967295 = (2^32)-1 int dbValueMin = UnsignedIntToSignedInt(min_uint); int dbValueMax = UnsignedIntToSignedInt(max_uint); uint valueFromDbMin = SignedIntToUnsignedInt(dbValueMin); uint valueFromDbMax = SignedIntToUnsignedInt(dbValueMax); System.Console.WriteLine(dbValueMin); System.Console.WriteLine(dbValueMax); System.Console.WriteLine(valueFromDbMin); System.Console.WriteLine(valueFromDbMax); } 
+5
source share
3 answers

To display from ulong to long , add and add long.MinValue . To go from long back to ulong , subtract long.MinValue and translate. In either case, use an unchecked context so that overflow conditions are ignored.

 public static long MapUlongToLong(ulong ulongValue) { return unchecked((long)ulongValue + long.MinValue); } public static ulong MapLongToUlong(long longValue) { return unchecked((ulong)(longValue - long.MinValue)); } 

The logic for uint and int is exactly the same.

+6
source

Necromancy.
General answer based on Tanner Swett answer:

 private static class Number<T> { private static object GetConstValue(System.Type t, string propertyName) { System.Reflection.FieldInfo pi = t.GetField(propertyName, System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic ); return pi.GetValue(null); } private static T GetMinValue<T>() { return (T)GetConstValue(typeof(T), "MinValue"); } private static T GetMaxValue<T>() { return (T)GetConstValue(typeof(T), "MaxValue"); } private static System.Func<T, T, T> CompileAdd<T>() { // Declare the parameters System.Linq.Expressions.ParameterExpression paramA = System.Linq.Expressions.Expression.Parameter(typeof(T), "a"); System.Linq.Expressions.ParameterExpression paramB = System.Linq.Expressions.Expression.Parameter(typeof(T), "b"); // Add the parameters System.Linq.Expressions.BinaryExpression body = System.Linq.Expressions.Expression.Add(paramA, paramB); // Compile it System.Func<T, T, T> add = System.Linq.Expressions.Expression.Lambda<System.Func<T, T, T>> (body, paramA, paramB).Compile(); return add; } private static System.Func<T, T, T> CompileSubtract<T>() { // Declare the parameters System.Linq.Expressions.ParameterExpression paramA = System.Linq.Expressions.Expression.Parameter(typeof(T), "a"); System.Linq.Expressions.ParameterExpression paramB = System.Linq.Expressions.Expression.Parameter(typeof(T), "b"); // Subtract the parameters System.Linq.Expressions.BinaryExpression body = System.Linq.Expressions.Expression.Subtract(paramA, paramB); // Compile it System.Func<T, T, T> subtract = System.Linq.Expressions.Expression.Lambda<System.Func<T, T, T>> (body, paramA, paramB).Compile(); return subtract; } public static T MinValue = GetMinValue<T>(); public static T MaxValue = GetMaxValue<T>(); public static System.Func<T, T, T> Add = CompileAdd<T>(); public static System.Func<T, T, T> Subtract = CompileSubtract<T>(); } public static TSigned MapUnsignedToSigned<TUnsigned, TSigned>(TUnsigned ulongValue) { TSigned signed = default(TSigned); unchecked { signed = Number<TSigned>.Add((TSigned)(dynamic)ulongValue, Number<TSigned>.MinValue); } return signed; } public static TUnsigned MapSignedToUnsigned<TSigned, TUnsigned>(TSigned longValue) { TUnsigned unsigned = default(TUnsigned); unchecked { unsigned = (TUnsigned)(dynamic) Number<TSigned> .Subtract(longValue, Number<TSigned>.MinValue); } return unsigned; } 

equivalent to:

 // return MapUnsignedToSigned<ulong, long>(ulongValue); private static long MapULongToLong(ulong ulongValue) { return unchecked((long)ulongValue + long.MinValue); } // return MapSignedToUnsigned<long, ulong>(longValue); private static ulong MapLongToUlong(long longValue) { return unchecked((ulong)(longValue - long.MinValue)); } 
0
source

Although Tanner Sweett is right. A nicer and messier solution is to tell .net to map access for ulong to the same memory address as long . This will give you instant conversion speed.

 void Main() { var foo = new Foo { Long = -1 }; Console.WriteLine(foo.ULong); } // Define other methods and classes here [StructLayout(LayoutKind.Explicit)] public class Foo { [FieldOffset(0)] private ulong _ulong; [FieldOffset(0)] private long _long; public long Long { get { return _long; } set { _long = value; } } public ulong ULong { get { return _ulong; } set { _ulong = value; } } } 

By setting up the POCO entity infrastructure to use the mapped attributes, you can manage the memory addresses to which the fields are bound.

Therefore, no conversion ever occurs.

This code is 100% faster than Tanner Swett.

-1
source

Source: https://habr.com/ru/post/1260617/


All Articles