#javascript #c# #double #rounding #calculation
#javascript #c# #двойной #округление #вычисление
Вопрос:
Я пытаюсь преобразовать код из C # в javascript.
Я выполнил эти 2 тестовые функции, в которых я выполняю вычисления в цикле. Исходный код — это код C #. Но кажется, что вычисления не показывают одинаковых результатов.
Это связано с тем, как работают значения floats, double и rounding. Но я не могу понять, что происходит не так.
Тогда мой вопрос должен заключаться в том, как мы можем преобразовать этот код C # в javascript, чтобы получить те же результаты?
В цикле cycle: 100-102, как показано ниже, они начинают показывать разные результаты:
C #
1.5E-08___100
3.01E-08___101
4.53E-08___102
javascript
1.5000000000002e-8___100
1.505e-08___101
1.51e-08___102
Код на C #
void csharpfunction() {
double TESTNUMBER = 0; List<double> procentLIST = new List<double>();
for (double i = 0; i < 300; i = 0.5) { procentLIST.Add(i); }
TESTNUMBER = Convert.ToDouble("0.00000001");
for (int t = 0; t < procentLIST.Count; t )
{
TESTNUMBER = TESTNUMBER * (1 (procentLIST[t] / 100));
listBox1.Items.Add(TESTNUMBER.ToString() "___" t);
TESTNUMBER = Math.Round(TESTNUMBER, 8);
}
}
Код Javascript
function javascriptfunction() {
var TESTNUMBER = 0; var i; var t; var procentLIST = [];
for (i = 0; i < 300; i = 0.5) { procentLIST.push(i); }
TESTNUMBER = ConvertToDouble("0.00000001");
for (t = 0; t < procentLIST.length; t ) {
TESTNUMBER = TESTNUMBER * (1 (procentLIST[t] / 100));
console.log(TESTNUMBER, "_____", t);
TESTNUMBER = MathRound(TESTNUMBER, 8);
}
}
function ConvertToDouble(x) {
return Number.parseFloat(x).toFixed(16);
}
function MathRound(num, nrdecimals) {
nrdecimals = Math.pow(10, nrdecimals);
return Math.floor(num * nrdecimals) / nrdecimals;
}
Комментарии:
1. Скорее всего, это путаница типов, например, получение строк, когда вам нужно число, или ошибки в математике с плавающей запятой JS.
2. Я думаю, мне просто хотелось бы понять, как можно было бы написать эту функцию C # для javascript. Это должно быть возможно любым способом. Я также полагаю, что это должно быть каким-то образом путаницей типов.
3. Вам действительно не следует использовать basic js для математики, поскольку вы, скорее всего, столкнетесь с математическими ошибками с плавающей запятой. Может быть, проверьте что-то вроде: npmjs.com/package/decimal.js
4. 64-разрядные значения с плавающей запятой имеют точность до 14 или 15 значащих цифр. Вы выводите число перед его округлением. «Разница» находится за пределами точности 64-разрядных плавающих значений на любом языке / платформе.
Ответ №1:
Вы можете использовать .toFixed
метод для округления с определенной точностью. Ваш MathRound
метод возвращает разные значения.
function javascriptfunction() {
var TESTNUMBER = 0; var i; var t; var procentLIST = [];
for (i = 0; i < 300; i = 0.5) { procentLIST.push(i); }
TESTNUMBER = ConvertToDouble("0.00000001");
for (t = 0; t < procentLIST.length; t ) {
TESTNUMBER = TESTNUMBER * (1 (procentLIST[t] / 100));
console.log(TESTNUMBER.toExponential(2), "_____", t);
TESTNUMBER = TESTNUMBER.toFixed(8);
}
}
function ConvertToDouble(x) {
return Number.parseFloat(x).toFixed(16);
}
javascriptfunction()
Комментарии:
1. Да, это действительно сработало там при округлении с использованием .toFixed(8). Большое вам спасибо за помощь!
2. 102 регистрируется
4.5299999999999995e-8_____102
не4.53e-8___102
3. использование @ChrisBrownie55
.toExponential
(обновил код)4. toFixed() не округляет, он только отображает (возвращает строку). Пример:
parseFloat((1.005).toFixed(5)).toPrecision(18)
возвращает"1.00499999999999989"
— и вы видите, и ничего не округлял.5. @Wiimm
1.00499999999999989.toFixed(3)
возвращает1.005
Ответ №2:
фрагмент
TESTNUMBER = Math.Round(TESTNUMBER, 8);
использует округление средней точки.Равное округление во время выполнения вашей функции
function MathRound(num, nrdecimals) {
nrdecimals = Math.pow(10, nrdecimals);
return Math.floor(num * nrdecimals) / nrdecimals;
}
выполняется ли округление в меньшую сторону