รับส่วนทศนิยมของตัวเลขด้วย JavaScript


248

ฉันมีตัวเลขลอยเหมือนและ3.21.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

ใช้ไม่ได้12

js> 2.3 % 1
0.2999999999999998

60
ในโลกที่ 0.2999999999999998 เท่ากับ 0.3 อาจยอมรับได้ สำหรับฉันมันไม่ใช่ ... ดังนั้นเพื่อแก้ปัญหานี้ฉันจะงดการใช้งานMath.*หรือ%การดำเนินการ
Marcel Stör

62
เพื่อหลีกเลี่ยงการจุดลอยปัดเศษปัญหาข้อสังเกตโดยใช้toFixedสามารถช่วยในบางสถานการณ์เช่น==(2.3 % 1).toFixed(4) "0.3000"
Brian M. Hunt

12
(2.3 % 1).toFixed(4).substring(2)= "3000"ถ้าคุณต้องการโดยไม่ต้องใช้0.
Simon_Weaver

14
ในโลกที่มีจำนวน2.3เกิดขึ้นและไม่ใช่2หรือ3จำนวน0.2999999999999998นั้นเป็นที่ยอมรับอย่างสมบูรณ์แม้จะดูถูกดูด้วยสายตามนุษย์ก็ตาม
Gershom

1
@GershomMaes มีหลายสถานการณ์ที่ไม่สามารถยอมรับหมายเลขนั้นได้
Adam Leggett

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

แม้ว่าสิ่งนี้จะไม่ทำงานสำหรับลบด้วยตัวเลขดังนั้นเราอาจต้องทำ

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

หากคุณมีส่วนจำนวนเต็มอยู่แล้วไม่จำเป็นต้องโทรMath.floor()อีกครั้งเพียงแค่ใช้ส่วนจำนวนเต็มที่คุณได้คำนวณไว้
tvanfosson

4
var n = 3.2, integr = Math.floor(n), decimal = n - integr;ใช้Math.floor ()เพียงครั้งเดียว integr = 3; decimal = 0.20000000000000018;
Nurlan

2
เพื่อที่จะทำงานร่วมกับจำนวนลบเพียงแค่สลับกับMath.floor Math.trunc
Igor Silva

นี่กลับมาเป็นจำนวนที่ไม่แน่นอนอย่างที่ฉันคาดหวังว่าจะได้รับ 0.80 จาก 100.80 ไม่ใช่ 0.79999 ... ฉันแก้ไขได้โดยการเพิ่มทศนิยมให้คงที่ (2)
Luis Febro

77

คุณสามารถแปลงเป็นสตริงได้ไหม

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

17
ใช้ได้ดีทุกที่ยกเว้นทวีปยุโรปที่มีเครื่องหมายจุลภาคคั่นด้วยทศนิยม หากคุณวางแผนที่จะใช้สิ่งนี้อย่าลืมพิจารณาด้วยว่าคุณเป็นชาวต่างชาติและตั้งเป้าหมายในยุโรปเนื่องจากโซลูชันนี้จะไม่ทำงานที่ยอดเยี่ยมสำหรับพวกเขา
cdmdotnet

8
ฉันมาจากคอนติเนนทอลยุโรปกับ French Firefox และใช้งานได้ โดยปกติเราจะใช้เครื่องหมายจุลภาคเป็นตัวคั่นทศนิยมในฝรั่งเศส เหตุผลที่เป็นใน JavaScript ไม่มีวัฒนธรรมเกี่ยวข้องเมื่อแปลง Number เป็นสตริงแม้ว่าฉันจะต้องการใช้n.toString()แทนn + ""เพราะสามารถอ่านได้มากกว่า
Gabriel Hautclocq

2
หากความเร็วมีความสำคัญก็n + ""ย่อมดีกว่า (ดูjsperf.com/number-vs-number-tostring-vs-string-number )
Gabriel Hautclocq

@cdmdotnet JS ใช้.เป็นตัวแยกทศนิยมเพื่อให้คุณใช้ได้ทุกที่ถ้าประเภทตัวแปรตัวแปรอินพุทของคุณลอย คุณต้องจัดการกับปัญหานั้นหากอินพุตของคุณเป็นสตริง ฉันยังต้องทราบว่าคำตอบนี้ส่งกลับสตริงในอาร์เรย์ ทางออกที่สมบูรณ์มากขึ้นคือparseFloat('0.' + (n + '').split('.')[1])
totymedli

@cdmdotnet โซลูชันอิสระที่ตั้งอยู่ที่นี่: stackoverflow.com/a/59469716/1742529
user1742529

32

0.29999999999999988 เป็นคำตอบที่ยอมรับได้อย่างไร ถ้าฉันเป็นผู้ถามฉันจะต้องการคำตอบของ. 3 สิ่งที่เรามีที่นี่คือความแม่นยำที่ผิดพลาดและการทดลองของฉันกับ floor,% และอื่น ๆ แสดงว่า Javascript ชอบความแม่นยำที่ผิดพลาดสำหรับการดำเนินการเหล่านี้ ดังนั้นฉันคิดว่าคำตอบที่ใช้การแปลงเป็นสตริงอยู่ในเส้นทางที่ถูกต้อง

ฉันจะทำสิ่งนี้:

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

โดยเฉพาะฉันใช้ 100233.1 และฉันต้องการคำตอบ ".1"


6
ฉันเห็นด้วยทั่วไป แต่คุณไม่สามารถพึ่งพา '.' regex เป็นตัวคั่นทศนิยมเป็นตัวละคร i18n
Marcel Stör

1
@jomofrodo ที่จริงแล้วบางคนอาจต้องการค่าที่ไม่ปัดเศษ ฉันจำหน่วย OP ไม่ได้เพื่อหาค่าที่ปัดเศษเพียงแยกค่า
VVV

1
@VVV ใช่บางคนอาจต้องการค่าที่ไม่ถูกปัดเศษ แต่เพียงเพราะคุณอาจต้องการความแม่นยำถึง 9 ตำแหน่งทศนิยมไม่ได้หมายความว่าข้อมูลอินพุตของคุณสนับสนุนจริง นั่นคือเหตุผลที่เรียกว่า "ความแม่นยำที่ผิดพลาด" หากอินพุตของคุณคือ 3.1 คำตอบที่แม่นยำที่สุดของคุณคือสิบอันดับแรกคือ .1 หากคุณตอบ. 09 แสดงว่าคุณได้คำนวณ / วัดความแม่นยำได้ถึง 100th จริง ๆ แล้วในความเป็นจริงการป้อนข้อมูลดั้งเดิมมีความแม่นยำถึงความแม่นยำที่ 10 เท่านั้น
jomofrodo

1
@ MarcelStörที่สามารถจัดการได้ง่าย: var decPart = (n.toLocaleString ("en")). split (".") [1];
jem

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

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
คุณช่วยอธิบายได้ไหมว่าเพราะเหตุใดภาษานี้จึงเป็นภาษาที่เป็นอิสระ มันเป็นจาวาสคริปต์
hotzst

4
@hotzst ไม่มีฟังก์ชั่นเฉพาะทางภาษา
Nurlan

1
ภาษาอิสระเพราะมันเป็นคณิตศาสตร์บริสุทธิ์ วิธีการแก้ปัญหาในทางปฏิบัติ ด้วยความยาวส่วนที่ต้องการ:var factor = Math.pow(10, desiredFractionLength); var fract = a * factor % factor / factor;
muratgozel

6

คุณสามารถใช้parseInt()ฟังก์ชั่นเพื่อรับส่วนจำนวนเต็มมากกว่าการใช้ฟังก์ชั่นเพื่อแยกส่วนทศนิยม

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

หรือคุณสามารถใช้ regex เช่น:

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

ทศนิยมกำลังจะมา0.20000000000000018... นี่เป็นการยากที่จะทำเพราะ0.2 < 0.20000000000000018ผลตอบแทนจริง .. 3.2 ควรกลับคืน 0.2: P สร้างความผิดปกติจำนวนมากและใช้.toFixed(2)สตริงผลตอบแทน: P
Himanshu Bansal

@HimanshuBansal นั่นเป็นปัญหาของ JavaScript (ทำคำถาม stackeoverflowให้กับคำถามนั้น) คุณสามารถใช้ methode ตัวที่สองที่ฉันแนะนำ
Sheki

ฉันมีคำแถลงปัญหาที่แตกต่างออกไปเล็กน้อย ... Kinda ใช้ทั้งสองวิธีของคุณ: P เพื่อแก้มัน .. ^^
Himanshu Bansal

@HimanshuBansal ดีใจที่โพสต์ของฉันช่วยแก้ปัญหาของคุณ!
Sheki

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

มันไม่สวย แต่ก็แม่นยำ


แน่นอนว่าเป็นสตริงดังนั้นคุณอาจจำเป็นต้องแยกวิเคราะห์ () ก่อนหากคุณต้องการให้เป็นตัวเลข คุณไม่จำเป็นต้อง parseFloat () ... เว้นแต่จะมีบางอย่างที่ฉันขาดหายไปที่นี่ด้วยฐาน 8 ไม่ใช่ฐาน 10 ตัวเลข ... สิ่งที่ฉันจำได้ยากเมื่อหลายปีก่อน
cdmdotnet

5

หากความแม่นยำมีความสำคัญและคุณต้องการผลลัพธ์ที่สอดคล้องกันนี่เป็นข้อเสนอบางประการที่จะส่งคืนส่วนทศนิยมของตัวเลขใด ๆ ที่เป็นสตริงรวมถึงส่วนนำ "0" หากคุณต้องการมันเป็นแบบลอยตัวให้เพิ่มvar f = parseFloat( result )เข้าไปในท้ายที่สุด

หากส่วนทศนิยมเท่ากับศูนย์จะส่งคืน "0.0" ตัวเลข Null, NaN และ undefined จะไม่ถูกทดสอบ

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

คุณสามารถอธิบาย "การแสดงตัวเลขเปลี่ยนเป็นวิศวกรรม" ได้ไหม นอกจากนี้การโลคัลไลซ์เซชันก็ไม่เกี่ยวข้องกันเพราะเราแค่ต้องการส่วนทศนิยมของตัวเลขไม่ใช่สตริงที่แปลเป็นภาษาท้องถิ่นแทนตัวเลข
Gabriel Hautclocq

4

คุณสามารถแปลงเป็นสตริงและใช้replaceวิธีการแทนส่วนจำนวนเต็มด้วยศูนย์จากนั้นแปลงผลลัพธ์กลับเป็นตัวเลข:

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

วิธีนี้จะใช้ไม่ได้ในทวีปยุโรปที่มีเครื่องหมายจุลภาคคั่นทศนิยมหรือไม่?
เพรสตัน

@preston คุณสามารถแทนที่จุดใน regex ด้วยอักขระตัวคั่นอื่น ๆ ที่คุณชอบ (เช่น/^[^,]/) แต่คุณควรปล่อยให้ผลลัพธ์เป็นสตริง (ลบตัว+ดำเนินการ) เพื่อหลีกเลี่ยง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 ในกรณีเหล่านั้น


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


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

เครื่องหมายทศนิยมแบบลอยตัวและรูปแบบตัวเลขสามารถขึ้นอยู่กับประเทศ ( .,) ดังนั้นวิธีแก้ปัญหาอิสระซึ่งเก็บรักษาส่วนจุดลอยตัวคือ:

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 สำหรับส่วนทศนิยม substracting
  5. ตอนนี้เรามีตัวเลขที่มีส่วนทศนิยมเป็นศูนย์ แต่ JavaScript สามารถให้ตัวเลขส่วนที่ลอยได้เพิ่มเติมซึ่งเราไม่ต้องการ
  6. ดังนั้นตัวเลข จำกัด เพิ่มเติมโดยการเรียกกับการนับตัวเลขในส่วนลอยลอยจำนวนเดิมtoFixed() xการนับจะถูกคำนวณตามความแตกต่างระหว่างความยาวของตัวเลขดั้งเดิมxกับตัวเลขnในการแทนสตริง

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

ง่ายมาก :)


-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
นั่นดูไม่เหมือนจาวาสคริปต์เลย!
Ch'marr

1
นี่ไม่ใช่จาวาสคริปต์
Amrut

ใน JS ควรเป็นดังนี้: var a = 3.2; var b = parseInt (a, 10); var c = a - b;
Ju-v
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.