我有一种处理.NET中某些地理坐标的方法,并且我有一个结构,该结构存储一个坐标对,以便如果将256传递给其中一个坐标,则将变为0。但是,在一个特定的实例中,计算大约255.9999998,因此存储在结构中。当它在tostring()中打印时,它变为256,不应该发生-256应该是0。我不介意它是否打印255.9999998,但是当调试器显示255.999999998时,它打印了256,这一事实是一个问题。将其存储和显示0会更好。

特别是比较存在问题。 255.99999998足够接近256,因此它应该等于它。比较双打时该怎么办?使用某种类型的Epsilon值?


编辑:具体来说,我的问题是我采用一个值,执行一些计算,然后对该数字执行相反的计算,我需要准确地恢复原始值。

有帮助吗?

解决方案

您可以使用Epsilon方法,但是Epsilon通常是一种软糖,可以解决浮点算术是有损的事实。

您可以考虑完全避免二进制浮点,并使用一个不错的理性课程。

如果您做无损算术,则上面的计算可能注定为256,因为您将获得理性类型。

理性类型可以按比例或分数类别的名称进行,并且编写非常简单

这是一个 例子。这是 其他


编辑....

要理解您的问题,请考虑,当小数值0.01转换为二进制表示时,它不能精确存储在有限内存中。该值的六边性表示为0.028F5C28F5C,其中“ 28F5C”无限重复。因此,即使在进行任何计算之前,您就可以通过以二进制格式存储0.01来放松精确性。

尽管有绩效成本,但使用理性和十进制类来克服这个问题。理性类型通过存储分子和分母来表示您的价值来避免此问题。小数类型使用二进制编码小数 格式, ,这可能会在分裂中有损失,但可以精确存储共同的小数值。

出于您的目的,我仍然建议一种理性类型。

其他提示

这听起来像是打印数字的问题,而不是如何存储数字。一种 double 有大约15个重要的数字,因此可以从256中告诉255.9999998,精确到备用。

您可以选择格式字符串,该字符串应该使您可以按照自己的方式显示数字中的大量数字。

比较双打平等的通常方法是减去它们,看看绝对值是否小于某些预定义的Epsilon,也许是0.000001。

您必须决定两个值相等的阈值。这相当于使用所谓的 固定点号 (而不是浮点)。然后,您必须手动执行舍入。

我会选择一些已知尺寸的未签名类型(例如UINT32或UINT64,如果它们可用,我不知道.NET),并将其视为固定点编号类型MOD 256。

例如。

typedef uint32 fixed;

inline fixed to_fixed(double d)
{
    return (fixed)(fmod(d, 256.) * (double)(1 << 24))
}

inline double to_double(fixed f)
{
    return (double)f / (double)(1 << 24);
}

或更详细的东西适合圆形惯例(到最接近,更低,更高,到奇数到偶数)。最高的8位固定位置保持整数,24个较低位保持分数部分。绝对精度为2^{ - 24}。

请注意,添加和提取此类数字自然要在256处包装。要乘法,您应该提防。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top