I am trying to perform some generic number manipulation independent of the number type. However, I know of no way to use generics to do this. The first idea was to filter the incoming types with a where statement, but all of the number types are closed and are, therefore, not valid for a generic filter. Also, the generics don't allow standard numeric operations (addition, shift, etc), so the only solution I can come up with is to re-write each method non-generically. Any other ideas?
For reference, following is the code that I initially tried:
private const int BYTE_SIZE = 8;
private const int UINT16_SIZE = 16;
private const int UINT32_SIZE = 32;
private const int UINT64_SIZE = 64;
public static byte[] ToBytes(UInt16[] pnaValues)
{
return ToSmaller<byte, UInt16>(pnaValues, BYTE_SIZE, UINT16_SIZE);
}
public static byte[] ToBytes(UInt32[] pnaValues)
{
return ToSmaller<byte, UInt32>(pnaValues, BYTE_SIZE, UINT32_SIZE);
}
....
public static UInt16[] ToUInt16s(byte[] pnaValues)
{
return ToLarger<UInt16, byte>(pnaValues, UINT16_SIZE, BYTE_SIZE);
}
public static UInt16[] ToUInt16s(UInt32[] pnaValues)
{
return ToSmaller<UInt16, UInt32>(pnaValues, UINT16_SIZE, UINT32_SIZE);
}
...
public static UInt64[] ToUInt64s(UInt32[] pnaValues)
{
return ToLarger<UInt64, UInt32>(pnaValues, UINT64_SIZE, UINT32_SIZE);
}
private static TLarger[] ToLarger<TLarger, TSmaller>(TSmaller[] pnaSmaller, int pnLargerSize, int pnSmallerSize)
where TLarger : byte, UInt16, UInt32, UInt64
where TSmaller : byte, UInt16, UInt32, UInt64
{
TLarger[] lnaRetVal = null;
int lnSmallerPerLarger = pnLargerSize / pnSmallerSize;
System.Diagnostics.Debug.Assert((pnLargerSize % pnSmallerSize) == 0);
if (pnaSmaller != null)
{
System.Diagnostics.Debug.Assert((pnaSmaller % lnSmallerPerLarger) == 0);
lnaRetVal = new TLarger[pnaSmaller.Length / lnSmallerPerLarger];
for (int i = 0; i < lnaRetVal.Length; i++)
{
lnaRetVal[i] = 0;
for (int j = 0; j < lnSmallerPerLarger; j++)
{
lnaRetVal[i] = (lnaRetVal[i] << pnLargerSize) + pnaSmaller[i * lnSmallerPerLarger + j];
}
}
}
return lnaRetVal;
}
private static TSmaller[] ToSmaller<TSmaller, TLarger>(TLarger[] pnaLarger, int pnSmallerSize, int pnLargerSize)
where TSmaller : byte, UInt16, UInt32, UInt64
where TLarger : byte, UInt16, UInt32, UInt64
{
TSmaller[] lnaRetVal = null;
int lnSmallerPerLarger = pnLargerSize / pnSmallerSize;
System.Diagnostics.Debug.Assert((pnLargerSize % pnSmallerSize) == 0);
if (pnaSmaller != null)
{
lnaRetVal = new TSmaller[pnaLarger.Length * lnSmallerPerLarger];
for (int i = 0; i < lnaRetVal.Length; i++)
{
for (int j = 0; j < lnSmallerPerLarger; j++)
{
lnaRetVal[i * lnSmallerPerLarger + (lnSmallerPerLarger - 1 - j)]
= pnaLarger[i] >> (j * pnLargerSize);
}
}
}
return lnaRetVal;
}
\c means you are escaping the "c" character, allowing you to print c \c means you are escaping the "\" character, which allows you to print \c. Escaping a character means that you are making the compiler ignore the character, if it is used for any functions or is reserved within a string.
C is a powerful general-purpose programming language. It can be used to develop software like operating systems, databases, compilers, and so on.
In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.
There's no common interface for arithmetic operations implemented by numeric types. Generic operators might help solving your problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With