Внедрение IEEE754 32-битной одинарной точности в игре

В популярной в настоящее время игре CSGO есть предметы. Каждому предмету присвоено значение с плавающей точкой. Каждый элемент имеет минимальное и максимальное значения, такие как 0-1 или 0,06-0,80. Каждое из этих значений может быть представлено 32-битной точностью IEEE754 с одинарной точностью. В игре есть возможность "обменять" 10 из этих предметов, чтобы создать один новый предмет. Когда вы торгуете 10 предметами, плавающий в результате предмет может быть рассчитан как

(avg of 10 floats)*(maxwear-of-resulting-item - minwear-of-resulting-item) + minwear-of-resulting-item

С чем я борюсь, так это потому, что CSGO использует IEEE754 Single Precision, среднее значение, такое как 0.07777777 как правило, в конечном итоге 0.0777777731418609619140625, Казалось бы, вы просто берете значение IEEE754 из приведенного выше уравнения, чтобы получить реальный результат с плавающей точкой, но у меня были комбинации из 10 элементов, где среднее значение было 0.0777777746 который должен был быть 0.0777777731418609619140625 но это закончилось как 0.077777780592441558837890625, Это означает, что CSGO выполняет расчеты другим способом или другим порядком, чем я знаю. Я перепробовал все комбинации, используя числа IEEE754 и взяв в среднем 10 предметов и поместив их в вышеприведенное уравнение, которое я могу придумать, но я до сих пор не могу найти функцию, которая работает для всех комбинаций из 10 предметов, которые я выбрасываю на него.

Лучшая функция, которую я придумал, это:

function ieee32(x) {
  var float = new Float32Array(1);
  float[0] = x;
  return float[0];
}

function getFloat(arr, max, min, actual) {
    for (let i = 0; i < 10; i++) {
        arr[i] = ieee32(arr[i]);
    }
    let total = 0;
    for (let i = 0; i < 10; i++) {
        total += arr[i];
        total = ieee32(total);
    }
    console.log("JavaScript: " + ieee32((total/10)*(max-min)+min) + " Actual: " + actual + "\n\n")
}

getFloat([0.038998112082481,0.057681135833263,0.065524280071259,0.05766910687089,0.059865914285183,0.057671267539263,0.048783712089062,0.10741865634918,0.13450133800507,0.14966422319412], 1, 0, "0.07777778059244");
getFloat([0.1836509257555,0.35303607583046,0.27028855681419,0.37463894486427,0.22707445919514,0.24045088887215,0.16390900313854,0.23315590620041,0.16496440768242,0.3563985824585], 0.80, 0.06, "0.250000000000000");
getFloat([0.2002295255661,0.1854835152626,0.35854259133339,0.27182018756866,0.21729451417923,0.33144646883011,0.37027344107628,0.23222900927067,0.22164261341095,0.1786058396101], 0.80, 0.06, "0.2500000000000000");
getFloat([0.46830454468727,0.31111705303192,0.32107254862785,0.15711317956448,0.15612974762917,0.16205121576786,0.16290606558323,0.24679513275623,0.36448866128922,0.21758955717087], 0.80, 0.06, "0.250000029802322");

К сожалению, это дает правильные ответы только для двух комбинаций. Можно ли как-нибудь найти правильный порядок вычислений и / или как они используют 32-разрядные представления одинарной точности IEEE754? Любые советы высоко ценится!

0 ответов

Другие вопросы по тегам