У меня есть небольшой трехмерный векторный класс в C # 3.0, основанный на struct, в которой в качестве базовой единицы используется double.
Пример: значение y одного вектора равно
-20.0 straight
Я вычитаю вектор со значением y
10.094999999999965
Значение для y, которое я ожидаю, равно
-30.094999999999963 (1)
Вместо этого я получаю
-30.094999313354492 (2)
Когда я делаю все вычисления в одном потоке, я получаю (1). Также отладчик и VS Quick-Watch возвращает (1). Но когда я запускаю несколько итераций в одном потоке, а затем вызываю функцию из другого потока, результатом является (2). Теперь отладчик также возвращает (2)!
Мы должны помнить, что .NET JIT может записывать значения обратно в память (веб-сайт Jon Skeet), что снижает точность с 80 бит (FPU) до 64 бит (двойная). Однако точность (2) намного ниже этой.
Класс вектор выглядит примерно так
public struct Vector3d
{
private readonly double _x, _y, _z;
...
public static Vector3d operator -(Vector3d v1, Vector3d v2)
{
return new Vector3d(v1._x - v2._x, v1._y - v2._y, v1._z - v2._z);
}
}
Вычисление так же просто, как это
Vector3d pos41 = pos4 - pos1;