Best collection to use with Double as key

I have this object:

Public Cactus{
    Public Double key;
    Public String value;
}

      

I have about ~ 100 Cactus

which have a unique key and a value that has some duplicates. However, I will need to get the value for the key by about 2000 times. My values Key

range from -10 to 280.

I want this process to be as fast as possible. What would be the best approach to do this? I thought using HashTable

, although I have always used one with Integer

, not Double

, and for some reason I am concerned that it is not recommended to use Double

both Key

.

Given my scenario, which collection would be the best to use?

+2


source to share


4 answers


Using a double as a key in a dictionary is usually a very bad idea. You will run into all of the presentation errors where you think you have stored 0.1 in the dictionary, but in fact you have stored something very close but not quite equal to 0.1.

I would suggest using a different type (string?) If you need exact matches.



If you don't want exact matches, but just find the closest value, consider something like SortedList instead.

+10


source


Yes, using a double value as a key seems awkward. Are these double values ​​the result of some computation that may have some very small round-off errors ? If you are going to calculate these values ​​and access the collection using these calculated values, it is very likely that there will be unwanted results.

For example, you store an item with a key of 1.01. Your calculations will result in 1.010000000000000123 and will not match the stored key.



If it is not, I see no problem using a double value as a key in a dictionary or hash table collection.

BTW using a typed dictionary (i.e. Dictionary<double, string>

) will be easier to use than HashTable

.

+2


source


I agree with @Mark Byers and @tafa that using a double key directly is a bad idea. If you want to make sure you have exactly the same number, you can create a string key based on the bytes that make up the double. The following structure maps a double value to the same memory space of 8 bytes, so no custom conversion is required.

[StructLayout(LayoutKind.Explicit)]
public struct TestStruct
{
    [FieldOffset(0)]
    public byte byte1;
    [FieldOffset(1)]
    public byte byte2;
    [FieldOffset(2)]
    public byte byte3;
    [FieldOffset(3)]
    public byte byte4;
    [FieldOffset(4)]
    public byte byte5;
    [FieldOffset(5)]
    public byte byte6;
    [FieldOffset(6)]
    public byte byte7;
    [FieldOffset(7)]
    public byte byte8;

    [FieldOffset(0)]
    public double double1;
}

      

It can then be wrapped in a function like this (assuming you have a struct defined in your class as a private variable)

static string GetStringKey(double key)
{
    _conversionStruct.double1 = Double.MaxValue;

    return String.Format("{0}:{1}:{2}:{3}:{4}:{5}:{6}:{7}", 
        _conversionStruct.byte1,
        _conversionStruct.byte2, 
        _conversionStruct.byte3, 
        _conversionStruct.byte4, 
        _conversionStruct.byte5,
        _conversionStruct.byte6, 
        _conversionStruct.byte7, 
        _conversionStruct.byte8);
}

      

And it is used like this.

var s1 = GetStringKey(double.MaxValue);
var s2 = GetStringKey(double.MinValue);

      

which gives ...

s1="255:255:255:255:255:255:239:127" 
s2="255:255:255:255:255:255:239:255"

      

+2


source


  • If you can do a double long and use that as a key. (multiply by 10 out of ten to get rid of the decimal point)
  • Another option, which is not as good as the first, is to convert the double to a string.
0


source







All Articles