Получить десятичную часть числа с помощью JavaScript

248

У меня есть числа с плавающей точкой, как 3.2и 1.6.

Мне нужно разделить число на целое и десятичное число. Например, значение 3.2будет разделено на два числа, то есть 3и0.2

Получить целую часть легко:

n = Math.floor(n);

Но у меня проблемы с получением десятичной части. Я пробовал это:

remainer = n % 2; //obtem a parte decimal do rating

Но это не всегда работает правильно.

Предыдущий код имеет следующий вывод:

n = 3.1 => remainer = 1.1

Что мне здесь не хватает?

Оскар
источник
1
Обратите внимание, что n = Math.floor(n);возвращается только желаемый результат (целочисленная часть) для неотрицательных чисел
tsemer
Проще % 1не использовать% 2
masterxilo

Ответы:

366

Используйте 1, нет 2.

js> 2.3 % 1
0.2999999999999998
Игнасио Васкес-Абрамс
источник
60
В мире, где 0,2999999999999998 равен 0,3, это может быть приемлемым. Для меня это не ... Следовательно, чтобы решить эту проблему, я бы воздержался от использования Math.*или %операций.
Марсель Стёр
62
Чтобы избежать проблем с округлением с плавающей запятой, использование toFixedможет помочь в некоторых ситуациях, например (2.3 % 1).toFixed(4)== "0.3000".
Брайан М. Хант
12
(2.3 % 1).toFixed(4).substring(2)= "3000"если вам это нужно без0.
Simon_Weaver
14
В мире, где число 2.3возникло, а не 2или 3, число 0.2999999999999998вполне приемлемо, несмотря на то, как оскорбительно оно выглядит для человеческих глаз.
Гершом
1
@GershomMaes существует множество обстоятельств, когда это число не приемлемо.
Адам Леггетт
92
var decimal = n - Math.floor(n)

Хотя это не будет работать для минус числа, поэтому нам, возможно, придется сделать

n = Math.abs(n); // Change to positive
var decimal = n - Math.floor(n)
greenimpala
источник
Если у вас уже есть целочисленная часть, вам не нужно Math.floor()повторно звонить - просто используйте целочисленную часть, которую вы рассчитали.
tvanfosson
4
var n = 3.2, integr = Math.floor(n), decimal = n - integr;используйте Math.floor () только один раз. integr = 3; decimal = 0.20000000000000018;
Нурлан
2
Для того , чтобы работать с отрицательным числом, просто поменять местами Math.floorс Math.trunc.
Игорь Сильва
это возвращало не точное число, как я ожидал получить 0,80 из 100,80, а не 0,79999 ... Я решил это, добавив decimal.toFixed (2)
Луис Февро
77

Вы могли бы преобразовать в строку, верно?

n = (n + "").split(".");
sdleihssirhc
источник
17
Это прекрасно работает везде, кроме континентальной Европы, где запятая, является десятичным разделителем. Если вы планируете использовать это, не забудьте учесть это, если вы многонациональны и ориентируетесь на Европу, так как это решение не поможет им.
cdmdotnet
8
Я из континентальной Европы с французским Firefox, и это работает. Обычно мы используем запятую в качестве десятичного разделителя во Франции. Причина в том, что в JavaScript нет никакой культуры при преобразовании числа в строку, хотя я бы предпочел использовать n.toString()вместо, n + ""потому что это более читабельно.
Габриэль Хаутлок
2
Если скорость критична, тогда n + ""действительно лучше (см. Jsperf.com/number-vs-number-tostring-vs-string-number )
Габриэль Хаутлок
@cdmdotnet JS использует .в качестве десятичного разделителя, поэтому у вас все будет хорошо, если тип входной переменной float. Вы должны иметь дело с этой проблемой, только если ваш ввод - строка. Я также должен отметить, что этот ответ возвращает строку в массиве. Более полное решениеparseFloat('0.' + (n + '').split('.')[1])
тотемедли
Решение для определения местоположения @cdmdotnet находится здесь: stackoverflow.com/a/59469716/1742529
user1742529
32

Как 0.2999999999999998 является приемлемым ответом? Если бы я был спрашивающим, я бы хотел получить ответ .3. Здесь мы имеем ложную точность, и мои эксперименты с floor,% и т. Д. Показывают, что Javascript любит ложную точность для этих операций. Поэтому я думаю, что ответы, использующие преобразование в строку, находятся на правильном пути.

Я бы сделал это:

var decPart = (n+"").split(".")[1];

В частности, я использовал 100233.1 и хотел получить ответ «.1».

jomofrodo
источник
6
Я в целом согласен, но вы не можете полагаться на «.» регулярное выражение в качестве десятичного разделителя является символом i18n .
Марсель Стёр
1
@jomofrodo На самом деле, некоторые могут хотеть не округленное значение. Я не помню, чтобы ОП запрашивала округленное значение, просто делю значения.
VVV
1
@VVV да, некоторым может понадобиться округленное значение. Но только то, что вам может потребоваться точность до 9 десятичных знаков, не означает, что ваши входные данные действительно поддерживают это. Вот почему это называется «ложная точность». Если вы введете 3,1, то ваш ответ может быть максимально точным - десятые, т. Е. 0,1. Если вы ответите .09, это означает, что вы фактически рассчитали / измерили точность до 100-й, тогда как на самом деле исходный вход был точным только с точностью до 10-й.
Джомофродо
1
@ MarcelStör, который легко обрабатывается: var decPart = (n.toLocaleString ("en")). Split (".") [1];
ДСР
1
.toString()не считает i18n. Десятичный разделитель всегда будет в . соответствии с MDN и спецификацией ECMA
Andrewmat
18

Вот как я это делаю, и я думаю, что это самый простой способ сделать это:

var x = 3.2;
int_part = Math.trunc(x); // returns 3
float_part = Number((x-int_part).toFixed(2)); // return 0.2
Zantafio
источник
15

Простой способ сделать это:

var x = 3.2;
var decimals = x - Math.floor(x);
console.log(decimals); //Returns 0.20000000000000018

К сожалению, это не возвращает точное значение. Однако это легко исправить:

var x = 3.2;
var decimals = x - Math.floor(x);
console.log(decimals.toFixed(1)); //Returns 0.2

Вы можете использовать это, если вы не знаете количество знаков после запятой:

var x = 3.2;
var decimals = x - Math.floor(x);

var decimalPlaces = x.toString().split('.')[1].length;
decimals = decimals.toFixed(decimalPlaces);

console.log(decimals); //Returns 0.2

Итан
источник
9

Независимый от языка способ:

var a = 3.2;
var fract = a * 10 % 10 /10; //0.2
var integr = a - fract; //3

обратите внимание, что это верно только для чисел с одной длиной фракции)

Нурлан
источник
3
Можете ли вы объяснить, почему вы думаете, что это не зависит от языка? Это JavaScript.
hotzst
4
@hotzst, нет специфической для языка функции
Нурлан
1
Язык не зависит, потому что это просто математика. Практическое решение. С желаемой длиной фракции:var factor = Math.pow(10, desiredFractionLength); var fract = a * factor % factor / factor;
Муратгозел
6

Вы можете использовать parseInt()функцию, чтобы получить целую часть, чем использовать это, чтобы извлечь десятичную часть

var myNumber = 3.2;
var integerPart = parseInt(myNumber);
var decimalPart = myNumber - integerPart;

Или вы можете использовать регулярные выражения, такие как:

splitFloat = function(n){
   const regex = /(\d*)[.,]{1}(\d*)/;
   var m;

   if ((m = regex.exec(n.toString())) !== null) {
       return {
          integer:parseInt(m[1]),
          decimal:parseFloat(`0.${m[2]}`)
       }
   }
}
Шеки
источник
грядет decimalPart 0.20000000000000018... это действительно становится трудно сделать, потому что 0.2 < 0.20000000000000018возвращает true .. 3.2 должно возвращать 0.2: P с таким количеством нарушений и использованием .toFixed(2)возвращаемой строки: P
Himanshu Bansal
@HimanshuBansal - это проблема JavaScript ( здесь вопрос о переполнении стека ). Вы можете использовать второй метод, который я предложил.
Шеки
Ну, у меня есть несколько иное постановление проблемы ... Кинда использовал оба пути: P, чтобы решить ее. ^^
Himanshu Bansal
@HimanshuBansal рад, что мой пост помог решить вашу проблему!
Шеки
5

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

var n = 2015.15;
var integer = Math.floor(n).toString();
var strungNumber = n.toString();
if (integer.length === strungNumber.length)
  return "0";
return strungNumber.substring(integer.length + 1);

Это не красиво, но это точно.

cdmdotnet
источник
Это, конечно, строка, поэтому вам может понадобиться сначала выполнить parseInt (), если вы хотите использовать ее как число. Вам не нужно анализировать parseFloat () ... если только что-то мне не хватает здесь с цифрой 8, а не 10, что я смутно помню много лет назад
cdmdotnet
5

Если точность имеет значение и вам требуются непротиворечивые результаты, вот несколько предложений, которые будут возвращать десятичную часть любого числа в виде строки, включая начальный «0». Если вам это нужно как поплавок, просто добавьте var f = parseFloat( result )в конце.

Если десятичная часть равна нулю, будет возвращено «0.0». Ноль, NaN и неопределенные числа не проверяются.

1. String.split

var nstring = (n + ""),
    narray  = nstring.split("."),
    result  = "0." + ( narray.length > 1 ? narray[1] : "0" );

2. String.substring, String.indexOf

var nstring = (n + ""),
    nindex  = nstring.indexOf("."),
    result  = "0." + (nindex > -1 ? nstring.substring(nindex + 1) : "0");

3. Math.floor, Number.toFixed, String.indexOf

var nstring = (n + ""),
    nindex  = nstring.indexOf("."),
    result  = ( nindex > -1 ? (n - Math.floor(n)).toFixed(nstring.length - nindex - 1) : "0.0");

4. Math.floor, Number.toFixed, String.split

var nstring = (n + ""),
    narray  = nstring.split("."),
    result  = (narray.length > 1 ? (n - Math.floor(n)).toFixed(narray[1].length) : "0.0");

Вот ссылка на jsPerf: https://jsperf.com/decpart-of-number/

Мы видим, что предложение № 2 является самым быстрым.

Габриэль Хаутлок
источник
не используйте ничего из этого. они сломаются, как только рендеринг числа переключится на разработку. они также не чувствительны к локали.
Spongman
Не могли бы вы объяснить «переключение рендеринга чисел в инженерное дело»? Кроме того, локализация не имеет значения, потому что нам нужна десятичная часть числа, а не локализованная строка, представляющая число.
Габриэль Hautclocq
4

Вы можете преобразовать его в строку и использовать replaceметод для замены целочисленной части на ноль, а затем преобразовать результат обратно в число:

var number = 123.123812,
    decimals = +number.toString().replace(/^[^\.]+/,'0');
gion_13
источник
Разве это решение не будет работать в континентальной Европе, где запятая является десятичным разделителем?
Престон
@preston Вы можете заменить точку в регулярном выражении любым другим символом-разделителем, который вам нравится (например, /^[^,]/), но вы должны оставить результат в виде строки (удалить +оператор), чтобы избежать NaNрезультатов.
gion_13
4

В зависимости от использования вы дадите потом, но это простое решение также может помочь вам.

Я не говорю, что это хорошее решение, но для некоторых конкретных случаев работает

var a = 10.2
var c = a.toString().split(".")
console.log(c[1] == 2) //True
console.log(c[1] === 2)  //False

Но это займет больше времени, чем предложенное решение @Brian M. Hunt

(2.3 % 1).toFixed(4)
Дэвид Санчес
источник
1
Это прекрасно работает везде, кроме континентальной Европы, где запятая, является десятичным разделителем. Если вы планируете использовать это, не забудьте учесть это, если вы многонациональны и ориентируетесь на Европу, так как это решение не поможет им.
cdmdotnet
1

У меня был случай, когда я знал, что у всех рассматриваемых чисел будет только один десятичный знак, и хотел получить десятичную дробь как целое число, поэтому я в итоге использовал такой подход:

var number = 3.1,
    decimalAsInt = Math.round((number - parseInt(number)) * 10); // returns 1

Это хорошо работает и с целыми числами, возвращая 0 в этих случаях.

peksipatongeis
источник
1

Я использую:

var n = -556.123444444;
var str = n.toString();
var decimalOnly = 0;

if( str.indexOf('.') != -1 ){ //check if has decimal
    var decimalOnly = parseFloat(Math.abs(n).toString().split('.')[1]);
}

Ввод: -556.123444444

Результат: 123444444

DavidDunham
источник
1

Математические функции работают быстрее, но всегда возвращают ненативные ожидаемые значения. Самый простой способ, который я нашел, это

(3.2+'').replace(/^[-\d]+\./, '')
Василий Суриков
источник
1

Хороший вариант - преобразовать число в строку, а затем разбить ее.

// Decimal number
let number = 3.2;

// Convert it into a string
let string = number.toString();

// Split the dot
let array = string.split('.');

// Get both numbers
// The '+' sign transforms the string into a number again
let firstNumber  = +array[0]; // 3
let secondNumber = +array[1]; // 2

В одной строке кода

let [firstNumber, secondNumber] = [+number.toString().split('.')[0], +number.toString().split('.')[1]];
Эрик Мартин Джордан
источник
0

Посмотрев на некоторые из них, я теперь использую ...

var rtnValue = Number(7.23);
var tempDec = ((rtnValue / 1) - Math.floor(rtnValue)).toFixed(2);
Патрик
источник
0

Хотя я очень поздно отвечаю на этот вопрос, пожалуйста, посмотрите код.

let floatValue = 3.267848;
let decimalDigits = floatValue.toString().split('.')[1];
let decimalPlaces = decimalDigits.length;
let decimalDivider = Math.pow(10, decimalPlaces);
let fractionValue = decimalDigits/decimalDivider;
let integerValue = floatValue - fractionValue;

console.log("Float value: "+floatValue);
console.log("Integer value: "+integerValue);
console.log("Fraction value: "+fractionValue)
Хифзур Рахман
источник
0

Десятичный знак и формат числа с плавающей точкой могут зависеть от country ( .,), поэтому независимое решение, которое сохранило часть с плавающей точкой:

getFloatDecimalPortion = function(x) {
    x = Math.abs(parseFloat(x));
    let n = parseInt(x);
    return Number((x - n).toFixed(Math.abs((""+x).length - (""+n).length - 1)));
}

- это интернационализированное решение, а не зависящее от местоположения:

getFloatDecimalPortion = x => parseFloat("0." + ((x + "").split(".")[1]));

Описание решения шаг за шагом:

  1. parseFloat() для гарантии входного сигнала
  2. Math.abs() во избежание проблем с отрицательными числами
  3. n = parseInt(x) для получения десятичной части
  4. x - n для вычитания десятичной части
  5. Теперь у нас есть число с нулевой десятичной частью, но JavaScript может дать нам дополнительные цифры с плавающей частью, которые нам не нужны
  6. Таким образом, ограничьте дополнительные цифры, вызывая их toFixed()с количеством цифр в плавающей части исходного числа с плавающей точкой x. Количество рассчитывается как разница между длиной исходного числа xи числа nв их строковом представлении.
user1742529
источник
-1

Используйте это:

function isNatural(n) {
    n = +n
    if (isNaN(n)) return 'NaN';
    return (n >= 0.0) && (Math.floor(n) === n) && n !== Infinity;
  }

Math.frac = function frac(x, m) {
    x = +x
    if (isNaN(x)) return NaN;
    if (isNatural(x) === true) return 0;
    m = +m || 1

      if (isNatural(x) === false && m === 1){
        var a = x.toString()
        var b = a.split('.')[1]
        var c = '0.' + b
        var d = +c
        return d;
      }

      if (isNatural(x) === false && m === 2){
        var a = x.toString()
        var b = a.split('.')[1]
        var c = +b
        return c;
      }

      if (isNatural(x) === false && m === 3){
        var a = x.toString()
        var b = a.split('.')[1]
        var c = '0.' + b
        var d = +c * 100
        return d;
      }    
  }

Math.fracФункция здесь имеет 3 режима работы :

Math.frac(11.635) //0.635
Math.frac(11.635, 1) //0.635 - default mode is 1
Math.frac(11.635, 2) //635
Math.frac(11.635, 3) //63,5 (%)

Это просто :)

Mr_DJA
источник
-9
float a=3.2;
int b=(int)a; // you'll get output b=3 here;
int c=(int)a-b; // you'll get c=.2 value here
user2381223
источник
4
это не похоже на javascript для меня!
Ch'marr
1
Это не сценарий Java
Amrut
В JS это должно быть так: var a = 3.2; var b = parseInt (a, 10); var c = a - b;
Ju-v