C# Dictionary 在计算时采用重复键/找不到键
C# Dictionary takes duplicate Keys / can't find Keys when calculated
我使用字典来存储图表的价格和数量信息。价格用作键,包含所有交易量信息的 class 作为值。
出于某种原因,当使用带有计算价格步长的 for 循环时(取最高价格并在每次迭代中按步长减去它,然后使用 Math.Round() 以确保它没有不需要的小数),似乎字典找不到某些实际存在的价格水平/键。然后它根据我的代码创建一个重复的密钥。就好像价格 Key,一个双精度值,会有不可见的小数点。
但是,使用 foreach 循环没有问题,除了在某些情况下它必须是 for 循环之外。
这是一些代码
double highestTick = Math.Round(ChartPanel.Y);
double lowestTick = Math.Round(ChartPanel.Y + ChartPanel.H);
for (double i = highestTick; i >= lowestTick; i -= TickSize)
double price = RoundToTickSize(i);
if (!traderLevelYDict.ContainsKey(price))
{
traderLevelYDict.Add(price, new volClass{});
}
else { ...... }
其中 RoundToTickSize() 很简单:
public double RoundToTickSize(double x)
{
return Math.Round(x / TickSize, MidpointRounding.ToEven) * TickSize; // TickSize is < 1
}
最后,我在字典中得到了一个重复的 Key,如图所示。请注意,价格后面没有空的 space 左右,而且我在打印前没有对值进行四舍五入。
知道它为什么这样做,以及如何阻止它吗?感谢所有回答!
感谢大力帮助,我发现 double 确实不精确,并且可能带有由于内部舍入错误而不会显示的小数位。
如果你 google 遇到诸如“双错误问题”或“双精度问题”之类的问题,你会发现许多人试图通过编写自定义方法来解决它,通过解析它们等来舍入双精度数。许多人建议改用十进制。
就我而言,唯一有效的方法是将价格/密钥双精度转换为整数,然后在需要时将其除以小数位数。
这里是关于原因的维基百科 link。
我使用字典来存储图表的价格和数量信息。价格用作键,包含所有交易量信息的 class 作为值。 出于某种原因,当使用带有计算价格步长的 for 循环时(取最高价格并在每次迭代中按步长减去它,然后使用 Math.Round() 以确保它没有不需要的小数),似乎字典找不到某些实际存在的价格水平/键。然后它根据我的代码创建一个重复的密钥。就好像价格 Key,一个双精度值,会有不可见的小数点。 但是,使用 foreach 循环没有问题,除了在某些情况下它必须是 for 循环之外。 这是一些代码
double highestTick = Math.Round(ChartPanel.Y);
double lowestTick = Math.Round(ChartPanel.Y + ChartPanel.H);
for (double i = highestTick; i >= lowestTick; i -= TickSize)
double price = RoundToTickSize(i);
if (!traderLevelYDict.ContainsKey(price))
{
traderLevelYDict.Add(price, new volClass{});
}
else { ...... }
其中 RoundToTickSize() 很简单:
public double RoundToTickSize(double x)
{
return Math.Round(x / TickSize, MidpointRounding.ToEven) * TickSize; // TickSize is < 1
}
最后,我在字典中得到了一个重复的 Key,如图所示。请注意,价格后面没有空的 space 左右,而且我在打印前没有对值进行四舍五入。
知道它为什么这样做,以及如何阻止它吗?感谢所有回答!
感谢大力帮助,我发现 double 确实不精确,并且可能带有由于内部舍入错误而不会显示的小数位。 如果你 google 遇到诸如“双错误问题”或“双精度问题”之类的问题,你会发现许多人试图通过编写自定义方法来解决它,通过解析它们等来舍入双精度数。许多人建议改用十进制。 就我而言,唯一有效的方法是将价格/密钥双精度转换为整数,然后在需要时将其除以小数位数。
这里是关于原因的维基百科 link。