Вычисления не показывают одинаковых результатов между C # и javascript

#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; 
}
  

выполняется ли округление в меньшую сторону