C# 通用随机数组生成器的界限

问题描述 投票:0回答:1

我编写了这段代码,试图创建一个通用的随机数组生成器(如果我必须自己这么说,这是一个非常有趣的方法)

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

如何在c#中获取通用数字类型的最大值和最小值

但是,我面临的问题是,由于与转换相关的一些复杂性,我似乎无法想出一种机制来设置最小和最大元素的边界/限制生成的随机数的范围。

最简单的模仿技术是什么:

_min + (*(t+i) / ratio);

其中比率计算为

(_MaxValue - _MinValue) / (_max - _min)

很明显,

_MaxValue - _MinValue
将是类型溢出,超出通用
T
的范围,所以我尝试使用
BigIntegers
来做到这一点,但我无法弄清楚这应该如何工作。

问题是我无法弄清楚如何将 BigInteger 结果转换回泛型类型

T
,就像我在大部分代码正文中所做的那样。

考虑到类型转换带来的复杂性,我将如何处理计算比率的情况,以便很好地定义它?

c# biginteger
1个回答
0
投票

更改

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;
}
© www.soinside.com 2019 - 2024. All rights reserved.