Nhận phần thập phân của một số bằng JavaScript


247

Tôi có số float như 3.21.6.

Tôi cần tách số thành phần nguyên và phần thập phân. Ví dụ: một giá trị 3.2sẽ được chia thành hai số, nghĩa là 30.2

Lấy phần nguyên là dễ dàng:

n = Math.floor(n);

Nhưng tôi gặp khó khăn khi lấy phần thập phân. Tôi đã thử điều này:

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

Nhưng nó không phải lúc nào cũng hoạt động chính xác.

Mã trước có đầu ra sau:

n = 3.1 => remainer = 1.1

Những gì tôi đang thiếu ở đây?


1
Lưu ý rằng n = Math.floor(n);chỉ trả về kết quả mong muốn của bạn (phần nguyên) cho các số không âm
tsTable

Sử dụng đơn giản % 1không% 2
masterxilo

Câu trả lời:


367

Sử dụng 1, không 2.

js> 2.3 % 1
0.2999999999999998

59
Trong một thế giới nơi 0,2999999999999998 bằng 0,3 thì điều này có thể được chấp nhận. Đối với tôi không phải là ... Do đó, để giải quyết thách thức này, tôi không sử dụng Math.*hoặc %vận hành.
Marcel Stor

62
Để tránh các vấn đề làm tròn điểm nổi được lưu ý, sử dụng toFixedcó thể giúp ích trong một số trường hợp, ví dụ (2.3 % 1).toFixed(4)== "0.3000".
Brian M. Hunt

12
(2.3 % 1).toFixed(4).substring(2)= "3000"nếu bạn cần mà không có0.
Simon_Weaver

14
Trong một thế giới nơi con số 2.3đã phát sinh, và không 2hoặc 3, con số 0.2999999999999998hoàn toàn có thể chấp nhận được mặc dù nó có vẻ xúc phạm đến mắt người như thế nào.
Gershom

1
@GershomMaes có nhiều tình huống mà con số đó không được chấp nhận.
Adam Leggett

92
var decimal = n - Math.floor(n)

Mặc dù điều này sẽ không hoạt động cho các số trừ vì vậy chúng tôi có thể phải làm

n = Math.abs(n); // Change to positive
var decimal = n - Math.floor(n)

Nếu bạn đã có phần nguyên, không cần phải gọi Math.floor()lại - chỉ cần sử dụng phần nguyên mà bạn đã tính.
tvanfosson

4
var n = 3.2, integr = Math.floor(n), decimal = n - integr;sử dụng Math.floor () chỉ một lần. integr = 3; decimal = 0.20000000000000018;
Nurlan

2
Để làm việc với số âm, chỉ cần trao đổi Math.floorvới Math.trunc.
Igor Silva

điều này đã trả về một con số không chính xác như tôi dự kiến ​​sẽ nhận được 0,80 từ 100,80 chứ không phải 0,79999 ... Tôi đã giải quyết điều này bằng cách thêm thập phân.toFixed (2)
Luis Febro

76

Bạn có thể chuyển đổi thành chuỗi, phải không?

n = (n + "").split(".");

17
Điều này hoạt động tốt ở mọi nơi trừ lục địa châu Âu nơi có dấu phẩy, là dấu phân cách thập phân. Nếu bạn có kế hoạch sử dụng điều này, hãy nhớ tính đến điều đó nếu bạn là người đa quốc gia và là người châu Âu mục tiêu, vì giải pháp này sẽ không làm tốt cho họ.
cdmdotnet

8
Tôi đến từ lục địa châu Âu với Firefox của Pháp và nó hoạt động. Thông thường chúng ta sẽ sử dụng dấu phẩy làm dấu tách thập phân ở Pháp. Lý do là trong JavaScript không có văn hóa liên quan khi chuyển đổi Số thành chuỗi, mặc dù tôi thích sử dụng n.toString()thay n + ""vì vì nó dễ đọc hơn.
Gabriel Hautclocq

2
Nếu tốc độ là rất quan trọng thì n + ""thực sự tốt hơn (xem jsperf.com/number-vs-number-tostring-vs-opes-number )
Gabriel Hautclocq

@cdmdotnet JS sử dụng .như một dấu tách thập phân để bạn ổn ở mọi nơi nếu loại biến đầu vào của bạn là float. Bạn chỉ phải đối phó với vấn đề đó nếu đầu vào của bạn là chuỗi. Tôi cũng phải lưu ý rằng câu trả lời này trả về một chuỗi trong một mảng. Một giải pháp hoàn chỉnh hơn làparseFloat('0.' + (n + '').split('.')[1])
totymedli 30/03/19

Giải pháp độc lập vị trí @cdmdotnet có tại đây: stackoverflow.com/a/59469716/1742529
user1742529

32

Làm thế nào là 0,2999999999999998 một câu trả lời chấp nhận được? Nếu tôi là người hỏi tôi sẽ muốn có câu trả lời .3. Những gì chúng ta có ở đây là độ chính xác sai và các thử nghiệm của tôi với sàn,%, v.v. chỉ ra rằng Javascript thích độ chính xác sai cho các hoạt động này. Vì vậy, tôi nghĩ rằng các câu trả lời đang sử dụng chuyển đổi thành chuỗi đang đi đúng hướng.

Tôi sẽ làm điều này:

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

Cụ thể, tôi đang sử dụng 100233.1 và tôi muốn câu trả lời ".1".


6
Tôi thường đồng ý nhưng bạn không thể dựa vào '.' regex là dấu phân cách thập phân là ký tự i18n .
Marcel Stor

1
@jomofrodo Trên thực tế, một số có thể muốn giá trị không làm tròn. Tôi không nhớ OP yêu cầu giá trị làm tròn, chỉ chia giá trị.
VVV

1
@VVV có, một số có thể muốn giá trị không làm tròn. Nhưng chỉ vì bạn có thể muốn độ chính xác đến 9 chữ số thập phân không có nghĩa là dữ liệu đầu vào của bạn thực sự hỗ trợ nó. Đó là lý do tại sao nó được gọi là "sai chính xác". Nếu đầu vào của bạn là 3,1, độ chính xác nhất mà câu trả lời của bạn có thể có là một phần mười, tức là .1. Nếu bạn trả lời .09, điều đó có nghĩa là bạn đã thực sự tính / đo xuống độ chính xác đến 100 giây, trong khi thực tế, đầu vào ban đầu chỉ chính xác đến độ chính xác 10 giây.
jomofrodo

1
@ MarcelStor có thể dễ dàng xử lý: var decPart = (n.toLocaleString ("en")). Split (".") [1];
Jem

1
.toString()không xem xét i18n. Dấu phân cách thập phân sẽ luôn . theo MDN và thông số ECMA
Andrewmat

18

Đây là cách tôi làm, mà tôi nghĩ là cách đơn giản nhất để làm điều đó:

var x = 3.2;
int_part = Math.trunc(x); // returns 3
float_part = Number((x-int_part).toFixed(2)); // return 0.2

15

Một cách đơn giản để làm điều đó là:

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

Thật không may, điều đó không trả về giá trị chính xác. Tuy nhiên, điều đó dễ dàng được sửa chữa:

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

Bạn có thể sử dụng điều này nếu bạn không biết số vị trí thập phân:

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

Ngôn ngữ độc lập:

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

lưu ý rằng nó chỉ đúng với các số có một chiều dài fractioanal)


3
Bạn có thể giải thích tại sao bạn nghĩ rằng đây là ngôn ngữ độc lập? Nó là JavaScript.
hotzst

4
@hotzst, không có chức năng ngôn ngữ cụ thể
Nurlan

1
Ngôn ngữ độc lập bởi vì nó chỉ là toán học thuần túy. Giải pháp thiết thực. Với độ dài phân đoạn mong muốn:var factor = Math.pow(10, desiredFractionLength); var fract = a * factor % factor / factor;
muratgozel

6

Bạn có thể sử dụng parseInt()hàm để lấy phần nguyên hơn là sử dụng phần đó để trích xuất phần thập phân

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

Hoặc bạn có thể sử dụng regex như:

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]}`)
       }
   }
}

binaryPart đang đến 0.20000000000000018... điều này thực sự khó thực hiện vì 0.2 < 0.20000000000000018trả về true .. 3.2 được cho là trả về 0,2: P tạo ra quá nhiều bất thường và sử dụng .toFixed(2)chuỗi trả về: P
Himanshu Bansal

@HimanshuBansal đó là một vấn đề JavaScript (có một câu hỏi khó hiểu về vấn đề này ). Bạn có thể sử dụng methode thứ hai những gì tôi đề xuất.
Sheki

Chà, tôi có một tuyên bố vấn đề hơi khác một chút ... Kinda đã sử dụng cả hai cách của bạn: P để giải quyết nó .. ^^
Himanshu Bansal

@HimanshuBansal rất vui vì bài viết của tôi đã giúp giải quyết vấn đề của bạn!
Sheki

5

Các công việc sau đây bất kể cài đặt khu vực cho dấu phân cách thập phân ... với điều kiện chỉ có một ký tự được sử dụng cho dấu phân cách.

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);

Nó không đẹp, nhưng nó chính xác.


Tất nhiên đó là một chuỗi, vì vậy bạn có thể không cần parseInt () trước nếu bạn muốn nó là một số. Bạn không cần phải phân tích cú pháp () ... trừ khi có thứ gì đó tôi thiếu ở đây với số 8 không phải là số 10 ... một cái gì đó tôi mơ hồ nhớ từ nhiều năm trước
cdmdotnet

5

Nếu độ chính xác quan trọng và bạn yêu cầu kết quả nhất quán, đây là một vài đề xuất sẽ trả về phần thập phân của bất kỳ số nào dưới dạng chuỗi, bao gồm cả "0." hàng đầu. Nếu bạn cần nó như một cái phao, chỉ cần thêm var f = parseFloat( result )vào cuối cùng.

Nếu phần thập phân bằng 0, "0,0" sẽ được trả về. Số không, NaN và số không xác định không được kiểm tra.

1. Chuỗi.split

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

2. String.sub chuỗi, 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");

Đây là một liên kết jsPerf: https://jsperf.com/decpart-of-number/

Chúng ta có thể thấy rằng đề xuất # 2 là nhanh nhất.


không sử dụng bất kỳ trong số này. chúng sẽ bị hỏng ngay khi kết xuất số chuyển sang kỹ thuật. họ cũng không nhạy cảm địa phương.
Spongman

Bạn có thể giải thích "chuyển đổi kết xuất số sang kỹ thuật"? Ngoài ra, nội địa hóa không liên quan vì chúng tôi chỉ muốn phần thập phân của một số, không phải là một chuỗi nội địa hóa đại diện cho một số.
Gabriel Hautclocq

4

Bạn có thể chuyển đổi nó thành một chuỗi và sử dụng replacephương thức để thay thế phần nguyên bằng 0, sau đó chuyển đổi kết quả trở lại thành một số:

var number = 123.123812,
    decimals = +number.toString().replace(/^[^\.]+/,'0');

Giải pháp này sẽ không hoạt động ở châu Âu lục địa trong đó dấu phẩy là dấu phân cách thập phân ??
preston

@preston Bạn có thể thay thế dấu chấm trong regex bằng bất kỳ ký tự dấu tách nào khác mà bạn thích (chẳng hạn như /^[^,]/), nhưng sau đó bạn nên để kết quả dưới dạng một chuỗi (loại bỏ +toán tử) để tránh NaNkết quả.
gion_13

4

Tùy thuộc vào cách sử dụng bạn sẽ cung cấp sau đó, nhưng giải pháp đơn giản này cũng có thể giúp bạn.

Tôi không nói đó là một giải pháp tốt, nhưng đối với một số trường hợp cụ thể hoạt động

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

Nhưng nó sẽ mất nhiều thời gian hơn giải pháp đề xuất của @Brian M. Hunt

(2.3 % 1).toFixed(4)

1
Điều này hoạt động tốt ở mọi nơi trừ lục địa châu Âu nơi có dấu phẩy, là dấu phân cách thập phân. Nếu bạn có kế hoạch sử dụng điều này, hãy nhớ tính đến điều đó nếu bạn là người đa quốc gia và là người châu Âu mục tiêu, vì giải pháp này sẽ không làm tốt cho họ.
cdmdotnet

1

Tôi đã có một trường hợp tôi biết tất cả các số trong câu hỏi sẽ chỉ có một số thập phân và muốn lấy phần thập phân dưới dạng số nguyên nên cuối cùng tôi đã sử dụng cách tiếp cận này:

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

Điều này cũng hoạt động độc đáo với số nguyên, trả về 0 trong những trường hợp đó.


1

Tôi đang dùng:

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]);
}

Đầu vào: -556.123444444

Kết quả: 123444444


1

Các hàm toán học nhanh hơn, nhưng luôn trả về giá trị không mong đợi riêng. Cách dễ nhất mà tôi tìm thấy là

(3.2+'').replace(/^[-\d]+\./, '')

1

Một lựa chọn tốt là chuyển đổi số thành một chuỗi và sau đó tách nó.

// 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

Trong một dòng mã

let [firstNumber, secondNumber] = [+number.toString().split('.')[0], +number.toString().split('.')[1]];

0

Sau khi xem xét một vài trong số này, bây giờ tôi đang sử dụng ...

var rtnValue = Number(7.23);
var tempDec = ((rtnValue / 1) - Math.floor(rtnValue)).toFixed(2);


0

Mặc dù tôi rất muộn để trả lời điều này, xin vui lòng xem mã.

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

Dấu thập phân dấu phẩy động và định dạng số có thể phụ thuộc vào quốc gia ( .,), vì vậy giải pháp độc lập, bảo toàn phần dấu phẩy động là:

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

- đó là giải pháp quốc tế hóa, thay vì phụ thuộc vào địa điểm:

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

Giải pháp từng bước một:

  1. parseFloat() để đảm bảo cocrrection đầu vào
  2. Math.abs() để tránh các vấn đề với số âm
  3. n = parseInt(x) để lấy phần thập phân
  4. x - n để trừ phần thập phân
  5. Hiện tại chúng tôi có số có phần thập phân bằng 0, nhưng JavaScript có thể cung cấp cho chúng tôi các chữ số phần nổi bổ sung mà chúng tôi không muốn
  6. Vì vậy, giới hạn các chữ số bổ sung bằng cách gọi toFixed()với số chữ số trong phần nổi của số float ban đầu x. Đếm được tính là chênh lệch giữa độ dài của số gốc xvà số ntrong biểu diễn chuỗi của chúng.

-1

Sử dụng cái này:

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

Các Math.fracchức năng ở đây có 3 chế độ:

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 (%)

Thật đơn giản :)


-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

4
Nó không giống như javascript đối với tôi!
Ch'marr

1
Đây không phải là tập lệnh java
Amrut

Trong JS, nó phải giống như: var a = 3.2; var b = parseInt (a, 10); var c = a - b;
Ju-v
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.