JavaScript ile bir sayının ondalık kısmını alma


248

Ben gibi şamandıra numaraları var 3.2ve 1.6.

Sayıyı tamsayı ve ondalık bölüme ayırmam gerekiyor. Örneğin, değeri 3.2iki sayıya bölünür, yani 3ve0.2

Tamsayı kısmını elde etmek kolaydır:

n = Math.floor(n);

Ama ondalık kısmı almakta sorun yaşıyorum. Bunu denedim:

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

Ancak her zaman düzgün çalışmaz.

Önceki kod aşağıdaki çıktıya sahiptir:

n = 3.1 => remainer = 1.1

Burada eksik olan ne?


1
n = Math.floor(n);Negatif olmayan sayılar için yalnızca istediğiniz sonucu (tamsayı kısmı) döndürdüğüne dikkat edin
tsemer

Basit kullanım % 1değil% 2
masterxilo

Yanıtlar:


366

Kullan 1, değil 2.

js> 2.3 % 1
0.2999999999999998

60
0.2999999999999998'in 0.3'e eşit olduğu bir dünyada bu kabul edilebilir. Bana göre ... Bu yüzden, bu zorluğu çözmek için kullanmaktan Math.*veya %operasyonlardan kaçınırdım .
Marcel Stör

62
Belirtilen kayan nokta yuvarlama sorunlarından kaçınmak için, kullanmak toFixedbazı durumlarda yardımcı olabilir , örneğin (2.3 % 1).toFixed(4)== "0.3000".
Brian M. Hunt

12
(2.3 % 1).toFixed(4).substring(2)= "3000"olmadan ihtiyacınız varsa0.
Simon_Weaver

14
Bir dünyada numara nerede 2.3ortaya ve henüz 2ya 3sayı, 0.2999999999999998insan gözlerine bakar hakaret nasıl rağmen mükemmel kabul edilebilir.
Gershom

1
@GershomMaes bu sayının kabul edilemez olduğu çeşitli durumlar vardır.
Adam Leggett

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

Bu eksi sayılar için işe yaramasa da,

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

Zaten bir tamsayı kısmına sahipseniz, Math.floor()tekrar aramanıza gerek yoktur - sadece hesapladığınız tamsayı kısmını kullanın.
tvanfosson

4
var n = 3.2, integr = Math.floor(n), decimal = n - integr;kullanmak Math.floor () sadece bir kez. integr = 3; decimal = 0.20000000000000018;
Nurlan

2
Negatif bir sayı ile çalışmak için, basitçe takas Math.floorile Math.trunc.
Igor Silva

Bu 0,9999 değil 100.80, 0,80 almak bekleniyor gibi kesin olmayan bir sayı döndürüyordu ... Ondalık.to sabit (2)
Luis Febro

77

Dizgeye dönüşebilirsin, değil mi?

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

17
Bu virgül ondalık ayırıcı olduğu kıta Avrupa hariç her yerde iyi çalışır. Bunu kullanmayı planlıyorsanız, çok uluslu ve hedef avrupaysanız, bunu dikkate almayı unutmayın, çünkü bu çözüm onlar için iyi bir iş yapmayacaktır.
cdmdotnet

8
Bir Fransız Firefox ile kıta Avrupa'sındanım ve işe yarıyor. Normalde virgülü Fransa'da ondalık ayırıcı olarak kullanırdık. JavaScript dizeye Numara dönüştürürken kullanmayı tercih ediyorum, ancak ilgili hiçbir kültürü olmadığını olmanın sebebi n.toString()yerine n + ""daha okunaklı olduğu için.
Gabriel Hautclocq

2
Hız kritikse n + ""gerçekten daha iyidir (bkz. Jsperf.com/number-vs-number-tostring-vs-string-number )
Gabriel Hautclocq

@cdmdotnet JS .ondalık ayırıcı olarak kullanır , bu nedenle girdi değişkeninizin türü float ise her yerde iyi olursunuz. Bu sorunla yalnızca girdiniz dizgiyse ilgilenmeniz gerekir. Ayrıca bu cevabın bir dizede bir dize döndürdüğünü not etmek zorundayım. Daha eksiksiz bir çözümparseFloat('0.' + (n + '').split('.')[1])
totymedli

@cdmdotnet konumdan bağımsız çözüm burada: stackoverflow.com/a/59469716/1742529
user1742529

32

0.2999999999999998 nasıl kabul edilebilir bir cevaptır? Ben asker olsaydım .3'ün cevabını almak isterdim. Burada sahip olduğumuz yanlış doğruluk ve floor,%, vb. İle yaptığım deneyler Javascript'in bu işlemler için yanlış hassasiyetten hoşlandığını gösteriyor. Dize dönüşüm kullanan cevaplar doğru yolda olduğunu düşünüyorum.

Bunu yapardım:

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

Özellikle, 100233.1 kullanıyordum ve ".1" cevabını istedim.


6
Genel olarak katılıyorum, ancak 'güvenemezsiniz'. ondalık ayırıcı olarak normal ifade bir i18n karakteridir .
Marcel Stör

1
@jomofrodo Aslında bazıları yuvarlanmamış değeri isteyebilir. OP'nin yuvarlatılmış bir değer istediğini hatırlamıyorum, sadece değerleri bölüyorum.
VVV

1
@VVV evet, bazıları yuvarlanmamış değeri isteyebilir. Ancak, 9 ondalık basamağa kadar hassasiyet isteyebileceğiniz, giriş verilerinizin gerçekten desteklediği anlamına gelmez. Bu yüzden buna "yanlış hassasiyet" denir. Eğer girdiniz 3.1 ise, cevabınızın sahip olabileceği en hassas kesinlik onuncudır, yani .1. .09 yanıtını verirseniz, aslında orijinal girdinin yalnızca 10. hassasiyete kadar doğru olduğu gerçekte 100. hassasiyete kadar hesapladığınız / ölçtüğünüz anlamına gelir.
jomofrodo

1
@ Kolayca işlenebilen MarcelStör: var decPart = (n.toLocaleString ("en")). Split (".") [1];
jem

1
.toString()i18n'yi dikkate almaz. Ondalık ayırıcı her zaman . MDN ve ECMA spesifikasyonuna
Andrewmat

18

Bunu yapmanın en basit yolu olduğunu düşünüyorum:

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

15

Bunu yapmanın basit bir yolu:

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

Ne yazık ki, bu kesin değeri döndürmez. Ancak, bu kolayca düzeltilebilir:

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

Ondalık basamak sayısını bilmiyorsanız bunu kullanabilirsiniz:

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

Dilden bağımsız yol:

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

sadece bir fraktioanal uzunluğa sahip sayılar için doğru olduğunu unutmayın)


3
Bunun neden dilden bağımsız olduğunu düşündüğünüzü açıklayabilir misiniz? JavaScript.
hotzst

4
@hotzst, dile özgü bir işlev yok
Nurlan

1
Dilden bağımsız çünkü sadece saf matematik. Pratik çözüm. İstenilen fraksiyon uzunluğu ile:var factor = Math.pow(10, desiredFractionLength); var fract = a * factor % factor / factor;
muratgozel

6

Sen kullanabilirsiniz parseInt()ondalık bölümünü açmaya kullanım daha tam sayı kısmını almak için işlevini

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

Veya aşağıdaki gibi regex kullanabilirsiniz:

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 geliyor 0.20000000000000018... bu gerçekten zor oluyor çünkü 0.2 < 0.20000000000000018geri dönüşler doğru .. 3.2 geri dönmesi gerekiyordu 0.2: P çok fazla düzensizlik yapma ve .toFixed(2)döndürme dizesini kullanma : P
Himanshu Bansal

@HimanshuBansal bu bir JavaScript sorunu (buna bir yığın akışı sorusu ). Önerdiğim ikinci yöntemi kullanabilirsiniz.
Sheki

Peki ben lil 'biraz farklı bir sorun bildirimi var ... Tür ur yolları her ikisi de kullanılır: P çözmek için .. ^^
Himanshu Bansal

@HimanshuBansal gönderimin sorununuzu çözmesine yardımcı olduğuna sevindim!
Sheki

5

Ondalık ayırıcı için bölgesel ayarlara bakılmaksızın aşağıdakiler çalışır ... bir ayırıcı için yalnızca bir karakter kullanılması koşuluyla.

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

Güzel değil, ama doğru.


Bu elbette bir dizedir, bu yüzden bir sayı olarak istiyorsanız ilk olarak parseInt () öğesine ihtiyacınız olabilir. ParseFloat () ... 'a ihtiyaç duymamalısınız. Burada temel 8 değil baz 10 sayıları ile kaçırdığım bir şey olmadığı sürece ... yıllar önce belirsiz bir şekilde hatırladığım bir şey
cdmdotnet

5

Duyarlılık önemliyse ve tutarlı sonuçlar gerekiyorsa, önde gelen "0" da dahil olmak üzere herhangi bir sayının ondalık kısmını dize olarak döndürecek birkaç öneri vardır. Bir şamandıra olarak ihtiyacınız varsa var f = parseFloat( result ), sonuna ekleyin .

Ondalık kısım sıfıra eşitse, "0.0" döndürülür. Null, NaN ve tanımsız sayılar test edilmez.

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

İşte bir jsPerf bağlantısı: https://jsperf.com/decpart-of-number/

En hızlı # 2 önerisinin olduğunu görebiliriz.


bunlardan hiçbirini kullanmayın. sayı oluşturma mühendisliğe geçer girmez kırılacaktır. aynı zamanda yerel ayarlara duyarlı değildir.
Spongman

"Mühendisliğe numara oluşturma anahtarları" açıklayabilir misiniz? Ayrıca, yerelleştirme ilgili değildir, çünkü bir sayıyı temsil eden yerelleştirilmiş bir dize değil, yalnızca bir sayının ondalık kısmını istiyoruz.
Gabriel Hautclocq

4

Bir dizeye dönüştürebilir replaceve tamsayı parçasını sıfır ile değiştirmek için yöntemi kullanabilir ve ardından sonucu bir sayıya dönüştürebilirsiniz:

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

Bu çözüm virgül ondalık ayırıcı olduğu kıta avrupa'da işe yaramaz mı?
preston

@preston Normal ifadedeki noktayı istediğiniz diğer ayırıcı karakterlerle (örneğin /^[^,]/) değiştirebilirsiniz, ancak sonuçlardan +kaçınmak için sonucu bir dize olarak bırakmanız ( operatörü kaldırmanız ) gerekir NaN.
gion_13

4

Daha sonra vereceğiniz kullanıma bağlı olarak, ancak bu basit çözüm size yardımcı olabilir.

Ben iyi bir çözüm demiyorum, ama bazı somut vakalar için çalışıyor

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

Ancak @Brian M. Hunt tarafından önerilen çözümden daha uzun sürecek

(2.3 % 1).toFixed(4)

1
Bu virgül ondalık ayırıcı olduğu kıta Avrupa hariç her yerde iyi çalışır. Bunu kullanmayı planlıyorsanız, çok uluslu ve hedef avrupaysanız, bunu dikkate almayı unutmayın, çünkü bu çözüm onlar için iyi bir iş yapmayacaktır.
cdmdotnet

1

Söz konusu tüm sayıların yalnızca bir ondalık sayıya sahip olacağını ve ondalık kısmı bir tamsayı olarak almak istediğini bildiğim bir durum vardı, bu yüzden bu tür bir yaklaşımı kullanarak bitirdim:

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

Bu, tamsayılarla da iyi çalışır ve bu durumlarda 0 döndürür.


1

Ben kullanıyorum:

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

Giriş: -556.123444444

Sonuç: 123444444


1

Matematik işlevleri daha hızlıdır, ancak her zaman yerel beklenen değerleri döndürmez. Bulduğum en kolay yol

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

1

İyi bir seçenek, sayıyı bir dizeye dönüştürmek ve sonra bölmektir.

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

Bir kod satırında

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

0

Bunlardan birkaçına baktıktan sonra şimdi kullanıyorum ...

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


0

Buna cevap vermek için çok geç olmama rağmen lütfen koda bir göz atın.

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

Kayan nokta ondalık işareti ve sayı biçimi ülkeye ( .,) bağlı olabilir , bu nedenle kayan nokta kısmını koruyan bağımsız çözüm:

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

- konuma bağlı yerine uluslararasılaştırılmış bir çözümdür:

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

Adım adım çözüm tanımı:

  1. parseFloat() girdi düzeltmeyi garanti etmek için
  2. Math.abs() negatif sayılarla ilgili sorunları önlemek için
  3. n = parseInt(x) ondalık kısmı almak için
  4. x - n ondalık bölümü çıkarmak için
  5. Şimdi sıfır ondalık kısmı olan bir sayımız var, ancak JavaScript bize istemediğimiz ek kayan parça rakamları verebilir
  6. Bu nedenle, toFixed()orijinal kayan nokta numarasının kayan kısmında basamak sayısı ile çağırarak ek basamakları sınırlayın x. Sayı, orijinal sayının uzunluğu ile dize gösterimlerindeki xsayı narasındaki fark olarak hesaplanır .

-1

Bunu kullan:

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

Buradaki Math.fracfonksiyonun 3 modu vardır:

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

Basit :)


-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
bu benim için javascript gibi görünmüyor!
Ch'marr

1
Bu java betiği değil
Amrut

JS'de şöyle olmalıdır: var a = 3.2; var b = parseInt (a, 10); var c = a - b;
Ju-v
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.