Potong (bukan pembulatan) angka desimal dalam javascript


93

Saya mencoba memotong angka desimal menjadi tempat desimal. Sesuatu seperti ini:

5.467   -> 5.46  
985.943 -> 985.94

toFixed(2)tidak hanya tentang hal yang benar tetapi membulatkan nilainya. Saya tidak ingin nilainya dibulatkan. Semoga ini mungkin dalam javascript.


6
jQuery hanyalah kerangka kerja dan masalah Anda tidak terkait dengan jQuery. Ini lebih tentang melakukan beberapa komputasi dasar dalam JavaScript. Saya harap Anda juga puas dengan solusi non-jQuery.
Felix Kling

Saya merasa terlalu banyak pekerjaan untuk mendapatkan perhitungan saya untuk mengembalikan hanya 2 desimal menggunakan Javascript. Saya dapat melakukannya dengan mudah dalam tampilan database saya. Saya menyadari bahwa metode ini tidak akan cocok untuk setiap situasi, tetapi saya ingin meletakkannya di sini karena dapat menghemat banyak waktu.
MsTapp

Jawaban:


51

upd :

Jadi, bagaimanapun, ternyata, bug pembulatan akan selalu menghantui Anda, tidak peduli seberapa keras Anda mencoba memberi kompensasi kepada mereka. Oleh karena itu, masalah harus ditangani dengan merepresentasikan angka persis dalam notasi desimal.

Number.prototype.toFixedDown = function(digits) {
    var re = new RegExp("(\\d+\\.\\d{" + digits + "})(\\d)"),
        m = this.toString().match(re);
    return m ? parseFloat(m[1]) : this.valueOf();
};

[   5.467.toFixedDown(2),
    985.943.toFixedDown(2),
    17.56.toFixedDown(2),
    (0).toFixedDown(1),
    1.11.toFixedDown(1) + 22];

// [5.46, 985.94, 17.56, 0, 23.1]

Solusi lama yang rawan kesalahan berdasarkan kompilasi dari orang lain:

Number.prototype.toFixedDown = function(digits) {
  var n = this - Math.pow(10, -digits)/2;
  n += n / Math.pow(2, 53); // added 1360765523: 17.56.toFixedDown(2) === "17.56"
  return n.toFixed(digits);
}

4
Ya, Prototipe tidak bekerja dengan andal lintas browser. Alih-alih mendefinisikan fungsi (tujuan terbatas) ini melalui sistem tipe, dengan cara yang tidak bekerja dengan andal, mengapa tidak meletakkannya di perpustakaan.
Thomas W

3
Ini tidak berfungsi seperti yang dikecualikan. Coba angka 17,56 dan angka = 2. Seharusnya 17,56, tetapi fungsi ini mengembalikan 17,55.
shendz

2
Dua ketidakkonsistenan dengan fungsi ini: Fungsi ini mengembalikan string sehingga 1.11.toFixedDown(1) + 22berakhir sebagai 1.122pengganti 23.1. Juga 0.toFixedDown(1)harus memproduksi 0tetapi malah menghasilkan -0.1.
Nick Knowlson

5
Perhatikan bahwa fungsi ini menghilangkan tanda negatif. Ex: (-10.2131).toFixedDown(2) // ==> 10.21.
rgajrawala

4
Juga (1e-7).toFixedDown(0) // ==> 1e-7,. Apakah itu untuk 1e-(>=7)(ex: 1e-8, 1e-9, ...).
rgajrawala

60

Jawaban Dogbert bagus, tetapi jika kode Anda mungkin harus berurusan dengan angka negatif, Math.floordengan sendirinya dapat memberikan hasil yang tidak terduga.

Misalnya Math.floor(4.3) = 4, tapiMath.floor(-4.3) = -5

Gunakan fungsi pembantu seperti ini untuk mendapatkan hasil yang konsisten:

truncateDecimals = function (number) {
    return Math[number < 0 ? 'ceil' : 'floor'](number);
};

// Applied to Dogbert's answer:
var a = 5.467;
var truncated = truncateDecimals(a * 100) / 100; // = 5.46

Berikut versi yang lebih nyaman dari fungsi ini:

truncateDecimals = function (number, digits) {
    var multiplier = Math.pow(10, digits),
        adjustedNum = number * multiplier,
        truncatedNum = Math[adjustedNum < 0 ? 'ceil' : 'floor'](adjustedNum);

    return truncatedNum / multiplier;
};

// Usage:
var a = 5.467;
var truncated = truncateDecimals(a, 2); // = 5.46

// Negative digits:
var b = 4235.24;
var truncated = truncateDecimals(b, -2); // = 4200

Jika itu bukan perilaku yang diinginkan, masukkan panggilan ke Math.absdi baris pertama:

var multiplier = Math.pow(10, Math.abs(digits)),

EDIT: shendz dengan benar menunjukkan bahwa menggunakan solusi ini dengan a = 17.56akan menghasilkan salah 17.55. Untuk mengetahui lebih lanjut tentang mengapa hal ini terjadi, baca Yang Harus Diketahui Setiap Ilmuwan Komputer Tentang Aritmatika Titik Mengambang . Sayangnya, menulis solusi yang menghilangkan semua sumber kesalahan floating-point cukup rumit dengan javascript. Dalam bahasa lain Anda akan menggunakan bilangan bulat atau mungkin tipe Desimal, tetapi dengan javascript ...

Solusi ini harus 100% akurat, tetapi juga akan lebih lambat:

function truncateDecimals (num, digits) {
    var numS = num.toString(),
        decPos = numS.indexOf('.'),
        substrLength = decPos == -1 ? numS.length : 1 + decPos + digits,
        trimmedResult = numS.substr(0, substrLength),
        finalResult = isNaN(trimmedResult) ? 0 : trimmedResult;

    return parseFloat(finalResult);
}

Bagi mereka yang membutuhkan kecepatan tetapi juga ingin menghindari kesalahan floating-point, cobalah sesuatu seperti BigDecimal.js . Anda dapat menemukan pustaka javascript BigDecimal lainnya dalam pertanyaan SO ini: "Apakah ada pustaka Javascript BigDecimal yang bagus?" dan inilah postingan blog yang bagus tentang perpustakaan matematika untuk Javascript


Mengapa tidak terduga? Mengubah arah pembulatan saat Anda berada di bawah 0, menyebabkan semua jenis artefak aritmatika & matematika jelek. Misalnya, angka dua kali lebih banyak akan dibulatkan menjadi 0, seperti bilangan bulat lainnya. Untuk grafik, akuntansi & banyak kegunaan lainnya, Anda akan mendapatkan hasil yang jelek. Sejujurnya, akan lebih sulit untuk mengatakan apa saran Anda baik untuk mengatakan apa yang tidak baik .
Thomas W

Ini bagus untuk apa yang dikatakannya - saat Anda ingin memotong desimal daripada membulatkan.
Nick Knowlson

1
Tidak akan berfungsi dengan 17.56 karena browser memberikan 17.56 * 100 = 1755.9999999999998 bukan 1756
shendz

Poin bagus shendz. Saya telah memperbarui jawaban saya dengan solusi yang menghilangkan semua kesalahan floating-point bagi mereka yang membutuhkannya.
Nick Knowlson

1
Ini tidak akan berfungsi untuk angka yang kurang dari 1 jika Anda tidak menginginkan desimal - truncateDecimals (.12345, 0) menghasilkan NaN kecuali Anda menambahkan tanda centang: if(isNAN(result) result = 0; Tergantung pada perilaku yang Anda inginkan.
Jeremy Witmer

35
var a = 5.467;
var truncated = Math.floor(a * 100) / 100; // = 5.46

5
Ini bekerja dengan baik tetapi akan memberikan hasil yang mungkin tidak diinginkan jika dia (atau orang lain yang melihat jawaban ini nanti) harus berurusan dengan angka negatif. Lihat stackoverflow.com/a/9232092/224354
Nick Knowlson

3
Mengapa tidak diinginkan? Mengubah arah pembulatan saat Anda berada di bawah 0, menyebabkan semua jenis artefak aritmatika.
Thomas W

8
Ada perbedaan antara pembulatan dan pemotongan. Memotong jelas perilaku yang dicari pertanyaan ini. Jika saya menelepon truncate(-3.14)dan menerima -4kembali, saya pasti akan menyebutnya tidak diinginkan.
Nick Knowlson

Saya setuju dengan Thomas. Perbedaan dalam perspektif mungkin datang dengan apakah Anda biasanya memotong untuk tampilan, atau untuk perhitungan. Dari perspektif komputasi, ini menghindari "artefak aritmatika"

3
var a = 65.1 var truncated = Math.floor(a * 100) / 100; // = 65.09 Karenanya ini bukan solusi yang tepat
Sanyam Jain

22

Anda dapat memperbaiki pembulatan dengan mengurangi 0,5 untuk toFixed, misalnya

(f - 0.005).toFixed(2)

1
Perhatian: karena ini tidak berfungsi untuk angka yang sangat kecil, angka dengan lebih dari 3 tempat desimal, atau angka negatif. Coba .0045, 5.4678 dan -5.467
Nick Knowlson

Ini akan berhasil selama Anda mencocokkan nilai yang Anda kurangi dengan panjang yang Anda inginkan. apa pun yang Anda berikan ke toFixed () harus berupa angka 0 setelah desimal.
dmarra

18

Pertimbangkan mengambil keuntungan dari tilde ganda:~~ .

Perhatikan nomornya. Kalikan dengan angka signifikan setelah desimal sehingga Anda dapat memotongnya menjadi nol tempat dengan ~~. Bagilah pengali itu kembali. Keuntungan.

function truncator(numToTruncate, intDecimalPlaces) {    
    var numPower = Math.pow(10, intDecimalPlaces); // "numPowerConverter" might be better
    return ~~(numToTruncate * numPower)/numPower;
}

Saya mencoba untuk menolak membungkus ~~panggilan dalam parens; urutan operasi harus membuat itu berfungsi dengan benar, saya yakin.

alert(truncator(5.1231231, 1)); // is 5.1

alert(truncator(-5.73, 1)); // is -5.7

alert(truncator(-5.73, 0)); // is -5

Tautan JSFiddle .

EDIT: Melihat ke belakang, saya secara tidak sengaja juga menangani kasus untuk melengkapi kiri desimal juga.

alert(truncator(4343.123, -2)); // gives 4300.

Logikanya agak aneh mencari penggunaan itu, dan mungkin mendapat manfaat dari refactor cepat. Tapi masih berhasil. Lebih beruntung dari pada kebaikan.


Ini adalah jawaban terbaik. Jika Anda memperluas Mathprototipe dengan ini dan memeriksa NaN-s sebelum mengeksekusi, itu akan sempurna.
Bartłomiej Zalewski

truncator((10 * 2.9) / 100, 2)mengembalikan 0,28 bukannya 0,29 ... jsfiddle.net/25tgrzq1
Alex

14

Solusi satu baris yang bagus:

function truncate (num, places) {
  return Math.trunc(num * Math.pow(10, places)) / Math.pow(10, places);
}

Kemudian sebut dengan:

truncate(3.5636232, 2); // returns 3.56
truncate(5.4332312, 3); // returns 5.433
truncate(25.463214, 4); // returns 25.4632

2
Saya suka solusi ini, tetapi perlu diingat bahwa ini tidak sepenuhnya didukung oleh semua browser. ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… )
Gene Parcellano

11

Saya pikir saya akan memberikan jawaban menggunakan |karena sederhana dan berfungsi dengan baik.

truncate = function(number, places) {
  var shift = Math.pow(10, places);

  return ((number * shift) | 0) / shift;
};

1
Panggilan yang bagus. Menggunakan operator bitwise memaksa nilainya menjadi int, dan oring dengan 0 berarti "simpan saja apa yang sudah kumiliki". Melakukan apa yang ~~dilakukan jawaban saya , tetapi dengan operasi bitwise tunggal. Meskipun memiliki batasan yang sama seperti yang tertulis juga: Kami tidak bisa melebihi 2 ^ 31 .
ruffin

1
tidak benar ketika truncate((10 * 2.9) / 100);kode ini mengembalikan 0,28 alih-alih 0,29 jsfiddle.net/9pf0732d
Alex

@Alex Seperti yang saya duga Anda menyadari ... selamat datang di JavaScript! . Ada perbaikan. Mungkin Anda ingin membagikannya? : D
ruffin

@ruffin Saya tahu tentang masalah ini =) Saya pikir jawaban ini adalah solusi untuk masalah ini. Sayangnya, saya belum menemukan solusi yang tepat, di mana-mana ada masalah seperti itu.
Alex


7

@ Jawaban Dogbert dapat ditingkatkan dengan Math.trunc, yang memotong alih-alih pembulatan.

Ada perbedaan antara pembulatan dan pemotongan. Memotong jelas perilaku yang dicari pertanyaan ini. Jika saya memanggil truncate (-3.14) dan menerima -4 kembali, saya pasti akan menyebutnya tidak diinginkan. - @NickKnowlson

var a = 5.467;
var truncated = Math.trunc(a * 100) / 100; // = 5.46
var a = -5.467;
var truncated = Math.trunc(a * 100) / 100; // = -5.46

1
Itu tidak bekerja di semua kasus yaitu console.log (Math.trunc (9.28 * 100) / 100); // 9.27
Mike Makuch

@MikeMakuch itu bukan masalah dengan Math.trunc, tetapi bukan 9.28 * 100merupakan 927.9999bukan 928. Anda mungkin ingin membaca The Perils of Floating Point
zurfyx

5

Saya menulis jawaban menggunakan metode yang lebih pendek. Inilah yang saya pikirkan

function truncate(value, precision) {
    var step = Math.pow(10, precision || 0);
    var temp = Math.trunc(step * value);

    return temp / step;
}

Metodenya bisa digunakan seperti itu

truncate(132456.25456789, 5)); // Output: 132456.25456
truncate(132456.25456789, 3)); // Output: 132456.254
truncate(132456.25456789, 1)); // Output: 132456.2   
truncate(132456.25456789));    // Output: 132456

Atau, jika Anda menginginkan sintaks yang lebih pendek, ini dia

function truncate(v, p) {
    var s = Math.pow(10, p || 0);
    return Math.trunc(s * v) / s;
}

ini adalah metode yang saya harapkan untuk digunakan
taxilian

4
Number.prototype.trim = function(decimals) {
    var s = this.toString();
    var d = s.split(".");
    d[1] = d[1].substring(0, decimals);
    return parseFloat(d.join("."));
}

console.log((5.676).trim(2)); //logs 5.67

Saya suka ini bekerja dengan string, sehingga menghilangkan nuansa angka floating point. Terima kasih!
iCode

4

Menurut saya fungsi ini bisa menjadi solusi sederhana:

function trunc(decimal,n=2){
  let x = decimal + ''; // string 
  return x.lastIndexOf('.')>=0?parseFloat(x.substr(0,x.lastIndexOf('.')+(n+1))):decimal; // You can use indexOf() instead of lastIndexOf()
}

console.log(trunc(-241.31234,2));
console.log(trunc(241.312,5));
console.log(trunc(-241.233));
console.log(trunc(241.2,0));  
console.log(trunc(241));


Dua tahun setelah ini diposting tetapi menemukan ini ketika saya mencoba untuk mencari cara terbaik menggunakan Math.trunc, regex, dll. Saya sangat menyukai solusi ini. Sangat sederhana tetapi berfungsi dengan sempurna (untuk kasus penggunaan saya).
giles123

Jangan lupa untuk memperhitungkan n = 0.
giles123

3

Saya menemukan masalah: mempertimbangkan situasi selanjutnya: 2.1 atau 1.2 atau -6.4

Bagaimana jika Anda ingin selalu 3 desimal atau dua atau berapa, jadi, Anda harus menyelesaikan angka nol di depan ke kanan

// 3 decimals numbers
0.5 => 0.500

// 6 decimals
0.1 => 0.10000

// 4 decimales
-2.1 => -2.1000

// truncate to 3 decimals
3.11568 => 3.115

Ini adalah fungsi tetap dari Nick Knowlson

function truncateDecimals (num, digits) 
{
    var numS = num.toString();
    var decPos = numS.indexOf('.');
    var substrLength = decPos == -1 ? numS.length : 1 + decPos + digits;
    var trimmedResult = numS.substr(0, substrLength);
    var finalResult = isNaN(trimmedResult) ? 0 : trimmedResult;

    // adds leading zeros to the right
    if (decPos != -1){
        var s = trimmedResult+"";
        decPos = s.indexOf('.');
        var decLength = s.length - decPos;

            while (decLength <= digits){
                s = s + "0";
                decPos = s.indexOf('.');
                decLength = s.length - decPos;
                substrLength = decPos == -1 ? s.length : 1 + decPos + digits;
            };
        finalResult = s;
    }
    return finalResult;
};

https://jsfiddle.net/huttn155/7/


x = 0.0000tes truncateDecimals (x, 2)gagal. kembali 0. tidak seperti yang diharapkan0.00
Ling Loeng

3
function toFixed(number, digits) {
    var reg_ex = new RegExp("(\\d+\\.\\d{" + digits + "})(\\d)")
    var array = number.toString().match(reg_ex);
    return array ? parseFloat(array[1]) : number.valueOf()
}

var test = 10.123456789
var __fixed = toFixed(test, 6)
console.log(__fixed)
// => 10.123456

3

Jawaban dari @kirilloid sepertinya adalah jawaban yang benar, namun kode utama perlu diperbarui. Solusinya tidak menangani angka negatif (yang disebutkan seseorang di bagian komentar tetapi belum diperbarui di kode utama).

Memperbarui itu menjadi solusi lengkap yang diuji:

Number.prototype.toFixedDown = function(digits) {
    var re = new RegExp("([-]*\\d+\\.\\d{" + digits + "})(\\d)"),
    m = this.toString().match(re);
    return m ? parseFloat(m[1]) : this.valueOf();
};

Contoh Penggunaan:

var x = 3.1415629;
Logger.log(x.toFixedDown(2)); //or use whatever you use to log

Riddle: JS Number Round down

PS: Repo tidak cukup untuk mengomentari solusi itu.


2

Berikut ini adalah fungsi sederhana namun berfungsi untuk memotong angka hingga 2 tempat desimal.

           function truncateNumber(num) {
                var num1 = "";
                var num2 = "";
                var num1 = num.split('.')[0];
                num2 = num.split('.')[1];
                var decimalNum = num2.substring(0, 2);
                var strNum = num1 +"."+ decimalNum;
                var finalNum = parseFloat(strNum);
                return finalNum;
            }

2

Jenis yang dihasilkan tetap berupa angka ...

/* Return the truncation of n wrt base */
var trunc = function(n, base) {
    n = (n / base) | 0;
    return base * n;
};
var t = trunc(5.467, 0.01);

2

Lodash memiliki beberapa metode utilitas Matematika yang dapat membulatkan , memberi lantai , dan langit - langit angka dengan ketepatan desimal tertentu. Ini meninggalkan nol tertinggal.

Mereka mengambil pendekatan yang menarik, menggunakan eksponen angka. Rupanya ini menghindari masalah pembulatan.

(Catatan: funcadalah Math.roundatau ceilatau floordalam kode di bawah)

// Shift with exponential notation to avoid floating-point issues.
var pair = (toString(number) + 'e').split('e'),
    value = func(pair[0] + 'e' + (+pair[1] + precision));

pair = (toString(value) + 'e').split('e');
return +(pair[0] + 'e' + (+pair[1] - precision));

Tautan ke kode sumber


1

Di sini pendapat saya tentang subjek:

convert.truncate = function(value, decimals) {
  decimals = (decimals === undefined ? 0 : decimals);
  return parseFloat((value-(0.5/Math.pow(10, decimals))).toFixed(decimals),10);
};

Ini hanya versi yang sedikit lebih rumit

(f - 0.005).toFixed(2)

1

Salah satu yang ditandai sebagai solusi adalah solusi yang lebih baik yang saya temukan sampai hari ini, tetapi memiliki masalah serius dengan 0 (misalnya, 0.toFixedDown (2) menghasilkan -0.01). Jadi saya sarankan untuk menggunakan ini:

Number.prototype.toFixedDown = function(digits) {
  if(this == 0) {
    return 0;
  }
  var n = this - Math.pow(10, -digits)/2;
  n += n / Math.pow(2, 53); // added 1360765523: 17.56.toFixedDown(2) === "17.56"
  return n.toFixed(digits);
}

1

Inilah yang saya gunakan:

var t = 1;
for (var i = 0; i < decimalPrecision; i++)
    t = t * 10;

var f = parseFloat(value);
return (Math.floor(f * t)) / t;

1
const TO_FIXED_MAX = 100;

function truncate(number, decimalsPrecison) {
  // make it a string with precision 1e-100
  number = number.toFixed(TO_FIXED_MAX);

  // chop off uneccessary digits
  const dotIndex = number.indexOf('.');
  number = number.substring(0, dotIndex + decimalsPrecison + 1);

  // back to a number data type (app specific)
  return Number.parseFloat(number);
}

// example
truncate(0.00000001999, 8);
0.00000001

bekerja dengan:

  • angka negatif
  • angka yang sangat kecil (presisi Number.EPSILON)

0

hanya untuk menunjukkan solusi sederhana yang berhasil untuk saya

konversikan menjadi string dan kemudian regex ...

var number = 123.45678;
var number_s = '' + number;
var number_truncated_s = number_s.match(/\d*\.\d{4}/)[0]
var number_truncated = parseFloat(number_truncated_s)

Itu bisa disingkat menjadi

var number_truncated = parseFloat(('' + 123.4568908).match(/\d*\.\d{4}/)[0])

0

Berikut adalah kode ES6 yang melakukan apa yang Anda inginkan

const truncateTo = (unRouned, nrOfDecimals = 2) => {
      const parts = String(unRouned).split(".");

      if (parts.length !== 2) {
          // without any decimal part
        return unRouned;
      }

      const newDecimals = parts[1].slice(0, nrOfDecimals),
        newString = `${parts[0]}.${newDecimals}`;

      return Number(newString);
    };

// your examples 

 console.log(truncateTo(5.467)); // ---> 5.46

 console.log(truncateTo(985.943)); // ---> 985.94

// other examples 

 console.log(truncateTo(5)); // ---> 5

 console.log(truncateTo(-5)); // ---> -5

 console.log(truncateTo(-985.943)); // ---> -985.94


0
Number.prototype.truncate = function(places) {
  var shift = Math.pow(10, places);

  return Math.trunc(this * shift) / shift;
};

0

Anda bisa bekerja dengan string. Ini Memeriksa apakah '.' ada, lalu menghapus bagian dari string.

memotong (7.88, 1) -> 7.8

memotong (7.889, 2) -> 7.89

memotong (-7.88, 1) -> -7.88

function  truncate(number, decimals) {
    const tmp = number + '';
    if (tmp.indexOf('.') > -1) {
        return +tmp.substr(0 , tmp.indexOf('.') + decimals+1 );
    } else {
        return +number
    }
 }

0

Saya agak bingung mengapa ada begitu banyak jawaban berbeda untuk pertanyaan yang sangat sederhana; hanya ada dua pendekatan yang saya lihat yang tampaknya layak untuk dilihat. Saya melakukan benchmark cepat untuk melihat perbedaan kecepatan menggunakan https://jsbench.me/ .

Ini adalah solusi yang saat ini (26/9/2020) ditandai sebagai jawaban:

function truncate(n, digits) {
    var re = new RegExp("(\\d+\\.\\d{" + digits + "})(\\d)"),
        m = n.toString().match(re);
    return m ? parseFloat(m[1]) : n.valueOf();
};

[   truncate(5.467,2),
    truncate(985.943,2),
    truncate(17.56,2),
    truncate(0, 1),
    truncate(1.11, 1) + 22];

Namun, ini melakukan hal-hal string dan regex, yang biasanya tidak terlalu efisien, dan ada fungsi Math.trunc yang melakukan persis seperti yang diinginkan OP hanya tanpa desimal. Oleh karena itu, Anda dapat dengan mudah menggunakannya ditambah sedikit aritmatika tambahan untuk mendapatkan hal yang sama.

Berikut adalah solusi lain yang saya temukan di utas ini, yang akan saya gunakan:

function truncate(n, digits) {
    var step = Math.pow(10, digits || 0);
    var temp = Math.trunc(step * n);

    return temp / step;
}

[   truncate(5.467,2),
    truncate(985.943,2),
    truncate(17.56,2),
    truncate(0, 1),
    truncate(1.11, 1) + 22];
    

Metode pertama adalah "99.92% lebih lambat" dari yang kedua, jadi yang kedua pasti yang saya sarankan untuk digunakan.

Oke, kembali mencari cara lain untuk menghindari pekerjaan ...

tangkapan layar benchmark

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.