Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Округление до нужного количества знаков после запятой (https://javascript.ru/forum/misc/2860-okruglenie-do-nuzhnogo-kolichestva-znakov-posle-zapyatojj.html)

Shurik_ 18.02.2009 18:49

Округление до нужного количества знаков после запятой
 
Привет всем! В отличии от PHP (функция round()), в яваскрипте нет функции округляющей до нужного знака после запятой. Есть только метод round, который округляет до целого числа.

Предлагаю Вам простую функцию, которая округляет до нужного знака.

function roundPlus(x, n) { //x - число, n - количество знаков 
  if(isNaN(x) || isNaN(n)) return false;
  var m = Math.pow(10,n);
  return Math.round(x*m)/m;
}


Предлагаю администрации портала внести эту функцию в список аналогов функций php, в качестве аналога функции round().

ZoNT 18.02.2009 19:01

alert(123.3453346.toFixed(3));

Андрей Параничев 18.02.2009 19:19

ZoNT,
toFixed возвращает значение типа string:
alert(typeof 123.3453346.toFixed(3)); // "string"


Поэтому лучше использовать его в комбинации с parseFloat:
alert(typeof parseFloat(123.3453346.toFixed(3))); // "number"

Kolyaj 18.02.2009 20:14

Цитата:

Сообщение от Андрей Параничев
toFixed возвращает значение типа string

А зачем еще может потребоваться округлить число до знака после запятой?

Shurik_ 18.02.2009 20:28

честно говоря, не нашел метод toFixed в справочнике, потому что он не описан в методах объекта Math, а описывается в методах объекта Number, его как бы приблизили к методам типа toString, и т.д. и возвращает он строку, хотя логически это чисто математическая штука должна быть.

Я думаю, в любом случае. в разделе "аналоги функций PHP" нужно указать аналог функции round() с использованием toFixing.

Kolyaj 18.02.2009 23:45

Цитата:

Сообщение от Shurik_
хотя логически это чисто математическая штука должна быть

В компьютерах немножко другая арифметика, нежели в школе, и там, по большому счету, подобное округление бессмысленно.

Андрей Параничев 19.02.2009 00:00

Kolyaj,
Цитата:

Сообщение от Kolyaj
А зачем еще может потребоваться округлить число до знака после запятой?

Может ты и прав, я не встречал таких задач, но думаю, что они бывают.

iyaki 10.12.2014 17:16

x.toFixed(n)/1;
так кажись проще

danik.js 10.12.2014 17:26

Вот тоже не понимаю зачем округлять, если нужны дальнейшие вычисления. Тогда же ошибка будет накапливаться.
Какая разница сколько знаков хранится в памяти. А вот при выводе уже можно урезать.

ruslan_mart 10.12.2014 18:03

alert(typeof +3.3453346.toFixed(3)); // "number"

kv9923 09.05.2016 15:48

Функция не работает, выдаёт roundPlus(2162.615, 2) = 2162.61 , а надо 2162.62.
Подскажите, в чем же ошибка ?

рони 09.05.2016 17:35

правильное округление
 
kv9923,
если хочется правильное округление ...
источник https://gist.github.com/andrew-alade...689745bc49d2b1
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">

</head>

<body>
<script>
String.prototype.lpad = function (padding, length) {
    var string = this;
    while (string.length < length) {
        string = padding + string;
    }
    return string;
}

Number.prototype.round = function(base) {
    if (base == null || base < 0) {
        return this;
    }

    var string = this.toString();
    var point_index = string.indexOf(".");
    if (point_index == -1) {
        return this;
    }
    var symbol_index = point_index + 1 + base;
    if (symbol_index >= string.length) {
        return this;
    }

    var integer        = parseInt(string.substring(0, point_index), 10);
    var fractional     = parseInt(string.substring(point_index + 1, point_index + 1 + base), 10) || 0;
    var max_fractional = Math.pow(10, base);
    var symbol         = parseInt(string.charAt(symbol_index), 10);
    if (symbol >= 5) {
        if (base == 0) {
            integer ++;
        } else {
            if (fractional + 1 == max_fractional) {
                integer ++;
                fractional = 0;
            } else {
                fractional ++;
            }
        }
    }

    return new Number(parseFloat(integer + "." + (fractional.toString().lpad("0", base))));
}

var a = 2162.615;
alert(a.round(2));
</script>

</body>
</html>

aklis 09.05.2016 18:16

Судя по всему это для рассчета денег.
Тогда до двух знаков можно так округлять, сместим точку, округлим в меньшую сторону и вернем точку назад :
Math.floor(n *100) /100

рони 09.05.2016 18:18

aklis,
:-? где 2162.62?
var n = 2162.615;  alert(Math.floor(n *100) /100);

aklis 09.05.2016 18:28

Пардон, присмотрелся и понял что ошибался, не для денег видимо, потому что в большую нужно. Тогда так:
function f(num, zeros) {
  var factor = +("1e" + zeros);
  return Math.ceil(num *factor) /factor;
};

aklis 09.05.2016 18:33

Надо отдохнуть, а то мозги заклинило и не могу понять, для денег таки в большую или меньшую надо?=) Щас еще подумал и уже выходит что в большую. Где-то недоплатишь потом и здравствуй пеня.

рони 09.05.2016 18:42

Цитата:

Сообщение от aklis
потому что в большую нужно

нужно округлять как Math.round но он тут не сработает, а сработает код выше пост 12

aklis 09.05.2016 18:47

рони
Да, хорошая округлялка, спасибо, уже утащил в кладовку:)

aklis 10.05.2016 19:26

До меня только сейчас дошло что Math.round вообщето сработает как надо в моей функции:)

function f(num, zeros) {
  var factor = +("1e" + zeros);
  return Math.round(num *factor) /factor;
};

f(123.124252,2) //123.12
f(123.125252,2) //123.13

рони 10.05.2016 19:49

:cray:
Цитата:

Сообщение от aklis
До меня только сейчас дошло что Math.round вообщето сработает как надо в моей функции

Цитата:

Сообщение от рони
нужно округлять как Math.round но он тут не сработает, а сработает код выше пост 12


aklis 10.05.2016 20:38

Дык работает же? Что не так там?

рони 10.05.2016 20:52

Цитата:

Сообщение от aklis
Дык работает же? Что не так там?

пост 14 возьмите число оттуда и получите нужный результат.

aklis 10.05.2016 20:59

А, ну да, это число в двоичном представлении бесконечная дробь жеж. Спасибо.

kv9923 18.05.2016 21:12

да, округление из поста 12 точно работает. Спасибо автору.
Попутно, подскажите, как правильно перемножить числа для дальнейшего округления:
90*24.85*0.97=2169.405 // выдает калькулятор, excel и тд
90*24.85*0.97=2169.4049999999997 // выдает javascript и округлялка соответственно неверно работает. Вместо 2169.41, выдает 2169.40.

рони 19.05.2016 00:10

округление чисел
 
kv9923,
а так?
Number.prototype.round = function(base) {
    if (base == null || base < 0) return this;
    var string = this.toString();
    var point_index = string.indexOf(".");
    if (point_index == -1) return this;
    var symbol_index = point_index + 1 + base;
    if (symbol_index >= string.length) return this;
    var max_fractional = Math.pow(10, base);
    var up = 0;
    string = string.split("");
    for (var i = string.length - 1; i >= symbol_index; i--) {
        if (point_index == i) continue;
        up = (string[i] = +string[i] + up) >= 5 ? 1 : 0;
        string[i] %= 10
    }
    string.length = symbol_index;
    return +(+string.join("") + up / max_fractional).toFixed(base)
};

var a = 90*24.85*0.97 ;
alert(a.round(2));

kv9923 21.05.2016 16:46

уже лучше, но 1*24.85*0.97=24.10 , а скрипт считает как 24.11.

рони 21.05.2016 17:11

kv9923,
неа 21.1045 что как раз и даст при округлении до второго знака 24.11 -- вы уж определитесь как вы хотите округлять и напишите функцию с нужными вам параметрами.

kv9923 21.05.2016 18:35

помогите сделать "Округление к ближайшему целому" — наиболее часто используемое округление, как это описано в вики по слову "Округление". Есть конечно и другие методы, но требуется реализовать именно этот. Думаю многие пользователи будут благодарны.
Округление 21.1045 (и 21.104999) до сотых даст 21.10.
Округление 21.1050 (и 21.114999) до сотых даст 21.11.

рони 21.05.2016 18:58

kv9923,
для такого округления достаточно toFixed
alert([21.1050.toFixed(2),21.1045.toFixed(2)] );

ms-pro 01.03.2020 03:35

Цитата:

Сообщение от Shurik_ (Сообщение 12858)
Привет всем! В отличии от PHP (функция round()), в яваскрипте нет функции округляющей до нужного знака после запятой. Есть только метод round, который округляет до целого числа.

Предлагаю Вам простую функцию, которая округляет до нужного знака.

Отлично работает, спасибо Shurik !!!)


Часовой пояс GMT +3, время: 04:35.