我编写了这段代码,试图创建一个通用的随机数组生成器(如果我必须自己这么说,这是一个非常有趣的方法)
public unsafe class RandomArray<T> : DynamicArray<T> where T : INumber<T> {
Type _type;
Random _r;
T _min;
T _max;
int _type_size;
T _MaxValue;
T _MinValue;
private void init(int capacity) {
_MaxValue = (T)typeof(T).GetField("MaxValue").GetValue(null);
_MinValue = (T)typeof(T).GetField("MinValue").GetValue(null);
// T ratio = T
// _MaxValue & _MinValue allow us to determine the ratio
_r = new Random();
generate(capacity);
_size = capacity;
}
private void generate(int capacity) {
// take into account _min & _max
byte[] b = new byte[capacity*_type_size+1];
_r.NextBytes(b);
fixed (byte* ptr_b = b) {
T* t = (T*)ptr_b;
for (int i = 0; i < capacity; i++) {
_data[i] = *(t+i);
}
};
}
public RandomArray(int capacity, T min, T max) : base(capacity+1) {
_type_size = Marshal.SizeOf(min);
_type = min.GetType();
_min = min;
_max = max;
init(capacity);
}
}
该代码是来自以下来源的概念的组合:
将字节解释为泛型类型
T
:
要获取通用原始数字类型的
MinValue
/MaxValue
:
但是,我面临的问题是,由于与转换相关的一些复杂性,我似乎无法想出一种机制来设置最小和最大元素的边界/限制生成的随机数的范围。
最简单的模仿技术是什么:
_min + (*(t+i) / ratio);
其中比率计算为
(_MaxValue - _MinValue) / (_max - _min)
很明显,
_MaxValue - _MinValue
将是类型溢出,超出通用T
的范围,所以我尝试使用BigIntegers
来做到这一点,但我无法弄清楚这应该如何工作。
问题是我无法弄清楚如何将 BigInteger 结果转换回泛型类型
T
,就像我在大部分代码正文中所做的那样。
考虑到类型转换带来的复杂性,我将如何处理计算比率的情况,以便很好地定义它?
更改
BigInteger
的类型并不简单。
我建议使用
Convert.ChangeType
方法,但它不会接受BigInteger
,因为它没有实现IConvertible
。
但是,
BigInteger
可以转换为数字类型,所以我会选择大数字类型(以防止任何信息丢失),让我们使用decimal
。当BigInteger
转换为十进制时,我们可以使用上述方法Convert.ChangeType
。
这是示例代码:
Console.WriteLine(Get<int>());
Console.WriteLine(Get<long>());
Console.WriteLine(Get<decimal>());
T Get<T>() where T : struct, IConvertible
{
BigInteger b = 1;
var t = (T)Convert.ChangeType((decimal)b, typeof(T));
return t;
}