Внедрение 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? Любые советы высоко ценится!