Mengapa typeNN mengembalikan 'angka'?


166

Hanya karena penasaran.

Tampaknya tidak terlalu logis yaitu typeof NaNangka. Ngomong -ngomong NaN === NaNatau NaN == NaNmembalas salah, omong-omong. Apakah ini salah satu kekhasan javascript, atau akankah ada alasan untuk ini?

Sunting: terima kasih atas jawaban Anda. Ini bukan hal yang mudah untuk membuat orang berkeliaran. Membaca jawaban dan wiki saya lebih mengerti, tapi tetap saja kalimatnya seperti

Perbandingan dengan NaN selalu mengembalikan hasil yang tidak terurut bahkan ketika membandingkan dengan itu sendiri. Predikat perbandingan adalah pensinyalan atau non-pensinyalan, versi pensinyalan menandakan pengecualian yang tidak valid untuk perbandingan semacam itu. Predikat persamaan dan persamaan adalah non-pensinyalan sehingga x = x false dapat digunakan untuk menguji apakah x adalah NaN yang sunyi.

hanya membuat kepalaku berputar. Jika seseorang dapat menerjemahkan ini dalam bahasa yang dapat dibaca manusia (berbeda dengan, katakanlah, ahli matematika), saya akan berterima kasih.


17
+1: "NaN adalah angka tetapi bukan angka. Hum ... apa?!"
sebelum

11
Untuk kesenangan ekstra; (NaN! == NaN) == true
Alex K.

1
Bahkan lebih menyenangkan (tetapi dapat dimengerti jika dipikir-pikir, isNaN mengembalikan boolean): isNaN (parseInt ('nodice')) === isNaN (parseInt ('someOtherNaN')) === true;
KooiInc

1
Jika menggunakan jQuery, saya lebih suka isNumericmemeriksa jenis: $.isNumeric(NaN); mengembalikan false, di mana $.type(NaN);, mengembalikan nomor. api.jquery.com/jQuery.isNumeric
Justin

3
Sebagai ahli matematika profesional, saya harus mengatakan bahwa kalimat memiliki sedikit kesamaan dengan bahasa matematika yang tepat.
Dmitri Zaitsev

Jawaban:


53

Artinya Bukan Angka. Ini bukan kekhasan javascript tetapi prinsip ilmu komputer yang umum.

Dari http://en.wikipedia.org/wiki/NaN :

Ada tiga jenis operasi yang mengembalikan NaN:

Operasi dengan NaN sebagai setidaknya satu operan

Formulir tidak ditentukan

  • Divisi 0/0, ∞ / ∞, ∞ / −∞, −∞ / ∞, dan −∞ / −∞
  • Perkalian 0 × ∞ dan 0 × −∞
  • Kekuatan 1 ^ ∞
  • Penambahan ∞ + (−∞), (−∞) + ∞ dan pengurangan setara.

Operasi nyata dengan hasil yang kompleks:

  • Akar kuadrat dari angka negatif
  • Logaritma angka negatif
  • Garis singgung kelipatan aneh 90 derajat (atau π / 2 radian)
  • Sinus atau cosinus terbalik dari angka yang kurang dari −1 atau lebih besar dari +1.

Semua nilai ini mungkin tidak sama. Tes sederhana untuk NaN adalah menguji value == valuesalah.


46
Tes yang lebih sederhana adalahisNaN(value)
Alsciende

4
@Alsciende itu tidak setara. isNaN(undefined)kembali true, tetapi undefined == undefinedjuga benar. Hal yang sama berlaku untuk semua jenis non-angka lain kecuali null.
Andy

7
Dengan kata lain, value !== valuemungkin merupakan cara terpendek untuk menguji apakah valuebenar NaN.
Andy

1
Sepertinya Anda benar, @Andy. Nah, itu kekhasan.
Alsciende

2
Ungkapan "nilai-nilai ini mungkin tidak sama" tidak memiliki arti, karena nilai-nilai itu tidak ada.
Dmitri Zaitsev

103

Yah, NaNmasih tipe numerik , meskipun sebenarnya singkatan dari Not-A-Number :-)

NaNhanya berarti nilai spesifik tidak dapat direpresentasikan dalam batasan tipe numerik (walaupun itu bisa dikatakan untuk semua angka yang harus dibulatkan agar pas, tetapi NaNmerupakan kasus khusus).

Spesifik NaNtidak dianggap sama dengan yang lain NaNkarena mereka mungkin nilai yang berbeda. Namun, NaNmasih merupakan tipe angka, sama seperti 2718 atau 31415.


Mengenai pertanyaan Anda yang diperbarui untuk dijelaskan dalam istilah awam:

Perbandingan dengan NaN selalu mengembalikan hasil yang tidak terurut bahkan ketika membandingkan dengan itu sendiri. Predikat perbandingan adalah pensinyalan atau non-pensinyalan, versi pensinyalan menandakan pengecualian yang tidak valid untuk perbandingan semacam itu. Predikat kesetaraan dan ketidaksetaraan adalah non-pensinyalan sehingga x = x return false dapat digunakan untuk menguji apakah x adalah NaN yang sunyi.

Semua ini berarti (dipecah menjadi beberapa bagian):

Perbandingan dengan NaN selalu mengembalikan hasil yang tidak terurut bahkan ketika membandingkan dengan itu sendiri.

Pada dasarnya, a NaNtidak sama dengan nomor lain, termasuk nomor lain NaN, dan bahkan termasuk nomor itu sendiri .

Predikat perbandingan adalah pensinyalan atau non-pensinyalan, versi pensinyalan menandakan pengecualian yang tidak valid untuk perbandingan semacam itu.

Mencoba melakukan perbandingan (kurang dari, lebih besar dari, dan sebagainya) operasi antara a NaNdan nomor lain dapat menghasilkan pengecualian yang dilemparkan (pensinyalan) atau hanya menjadi salah sebagai hasilnya (non-pensinyalan atau diam).

Predikat kesetaraan dan ketidaksetaraan adalah non-pensinyalan sehingga x = x return false dapat digunakan untuk menguji apakah x adalah NaN yang sunyi.

Tes untuk kesetaraan (sama dengan, tidak sama dengan) tidak pernah memberi sinyal sehingga menggunakannya tidak akan menyebabkan pengecualian. Jika Anda memiliki nomor reguler x, maka x == xakan selalu benar. Jika xa NaN, maka x == xakan selalu salah. Ini memberi Anda cara untuk mendeteksi NaNdengan mudah (diam-diam).


1
penjelasan yang baik, meskipun saya tidak setuju dalam dua kalimat terakhir: cara yang lebih baik untuk memeriksa apakah x adalah NaN menggunakan fungsi isNaN ()
Carlos Barcelona

@DominicRodger inilah yang saya pikirkan: typeof a === 'number'berarti "a disimpan secara internal sebagai pelampung IEEE 754"
Andy

Mengapa Infinity === Infinitykembali truejika suatu Infinitydapat diproduksi oleh nilai yang berbeda: 1.0 / 0.0 atau 2.0 / 0.0?
Hashem Qolami

1
@ Hasem, sangat mungkin karena mereka dianggap tak terbatas yang sama. Memperlakukan pembagian sebagai pengurangan berulang, tidak ada bedanya apakah Anda mulai dari dua atau satu, itu adalah jumlah langkah yang sama yang diperlukan untuk mencapai (atau, lebih tepatnya, tidak mencapai) nol. Saya mengerti guru matematika memiliki kelas infinity yang berbeda tetapi (1) Saya curiga 1/0dan 2/0berbaring di kelas yang sama dan (2) hanya ada satu kelas infinity di IEEE754 (selain +/-tentu saja).
paxdiablo

1
Saya tidak mengetahui cara untuk mendefinisikan "angka aktual" yang luar biasa ini dengan cara yang berarti. Dalam matematika, log dan akar negatif hanya dapat diperoleh melalui perluasan real ke bilangan kompleks, di mana mereka mengevaluasi ke beberapa nilai, dan 0/0tidak didefinisikan dengan cara yang berarti, selain mengatakan "nilainya" adalah seluruh rangkaian angka. Dan bahkan jika mereka didefinisikan, Math.log(-1) == Math.log(-1)masih dievaluasi false. Jadi tidak hanya tidak ada "angka aktual" selain NaNtetapi bahkan jika ada, mereka tidak digunakan untuk perbandingan.
Dmitri Zaitsev

20

ECMAScript (JavaScript) menspesifikasikan standar yang Numbersadalah IEEE 754 mengapung, yang meliputi NaNsebagai nilai mungkin.

ECMA 262 5e Bagian 4.3.19 : Nilai angka

nilai primitif yang sesuai dengan nilai biner format 64EE bit presisi ganda 64-bit.

ECMA 262 5e Bagian 4.3.23 : NaN

Nilai angka yang merupakan nilai IEEE 754 "Not-a-Number".

IEEE 754 di Wikipedia

Standar IEEE untuk Aritmatika Floating-Point adalah standar teknis yang ditetapkan oleh Institute of Electrical and Electronics Engineers dan standar yang paling banyak digunakan untuk perhitungan floating-point [...]

Standar mendefinisikan

  • format aritmatika : set data titik-mengambang biner dan desimal, yang terdiri dari angka-angka terbatas (termasuk angka nol yang ditandatangani dan angka-angka subnormal), infinities, dan nilai-nilai "bukan angka" khusus (NaNs)

[...]


8

typeof NaNkembali 'number'karena:

  • ECMAScript spec mengatakan tipe Number termasuk NaN:

    4.3.20 Jenis nomor

    set semua nilai Number yang mungkin termasuk nilai “Not-a-Number” (NaN) khusus, infinity positif, dan infinity negatif

  • Jadi typeofkembalilah sesuai:

    11.4.3 Jenis Operator

    Produksi UnaryExpression : typeof UnaryExpression dievaluasi sebagai berikut:

    1. Biarkan val menjadi hasil evaluasi UnaryExpression .
    2. Jika Tipe ( val ) adalah Referensi , maka
      1. Jika IsUnresolvableReference ( val ) benar , kembali"undefined" .
      2. Biarkan val menjadi GetValue ( val ).
    3. Mengembalikan String ditentukan oleh Type ( val ) sesuai dengan Tabel 20.

                    Table 20 — typeof Operator Results
    ==================================================================
    |        Type of val         |              Result               |
    ==================================================================
    | Undefined                  | "undefined"                       |
    |----------------------------------------------------------------|
    | Null                       | "object"                          |
    |----------------------------------------------------------------|
    | Boolean                    | "boolean"                         |
    |----------------------------------------------------------------|
    | Number                     | "number"                          |
    |----------------------------------------------------------------|
    | String                     | "string"                          |
    |----------------------------------------------------------------|
    | Object (native and does    | "object"                          |
    | not implement [[Call]])    |                                   |
    |----------------------------------------------------------------|
    | Object (native or host and | "function"                        |
    | does implement [[Call]])   |                                   |
    |----------------------------------------------------------------|
    | Object (host and does not  | Implementation-defined except may |
    | implement [[Call]])        | not be "undefined", "boolean",    |
    |                            | "number", or "string".            |
    ------------------------------------------------------------------

Perilaku ini sesuai dengan Standar IEEE untuk Aritmatika Floating-Point (IEEE 754) :

4.3.19 Nilai angka

nilai primitif yang sesuai dengan nilai biner format 64-bit presisi ganda nilai IEEE 754

4.3.23 NaN

nilai angka yang merupakan nilai IEEE 754 “Bukan Angka”

8.5 Jenis Angka

Tipe angka persis 18437736874454810627 (yaitu, 2 53 −2 64 +3) nilai, mewakili nilai IEEE 754 format 64-bit presisi ganda sebagaimana ditentukan dalam Standar IEEE untuk Aritmatika Binary Floating-Point, kecuali bahwa 9007199254740990 ( yaitu, 2 53 −2) nilai “Not-a-Number” berbeda dari Standar IEEE diwakili dalam ECMAScript sebagai nilai NaN khusus tunggal . (Perhatikan bahwa nilai NaN dihasilkan oleh ekspresi program NaN.)


5

NaN adalah nilai floating point yang valid ( http://en.wikipedia.org/wiki/NaN )

dan NaN === NaN salah karena mereka tidak harus non-angka yang sama


1
Maaf tapi saya harus mengatakan itu bukan cara yang baik untuk memikirkannya. "tidak harus sama non-angka" tidak berarti mereka selalu berbeda dan membandingkannya harus menghasilkan salah. Yang terbaik adalah tidak mengukur NaN dan menganggapnya sebagai keanehan dalam basis pengetahuan kami.
Dave

1
Jadi mengapa semua Infinityitu identik? Adakah pikiran?
Hashem Qolami

5

NaN != NaNkarena mereka tidak perlu SAMA non-angka. Jadi itu masuk akal ... Juga mengapa mengapung memiliki keduanya +0,00 dan -0,00 yang tidak sama. Pembulatan dapat melakukan itu mereka sebenarnya tidak nol.

Adapun typeof, itu tergantung pada bahasa. Dan sebagian besar bahasa akan mengatakan bahwa NaN adalah float, double atau angka tergantung pada bagaimana mereka mengklasifikasikannya ... Saya tahu tidak ada bahasa yang akan mengatakan ini adalah tipe yang tidak diketahui atau nol.


1
ehr, pertimbangkan: var x = parseInt ('no dadu'), y = x; Sekarang saya akan mengatakan bahwa kedua NaN persis sama? Tapi tidak, x === y mengembalikan false juga.
KooiInc

ya, tetapi Anda tidak bisa PASTI, dan dengan demikian mereka tidak sama. Ini adalah logika yang sama dengan logika NULLable dalam database. Meskipun banyak orang menganggap mereka sama dengan null pointer dari bahasa pemrograman lain, mereka ternyata memiliki semantik yang sama sekali berbeda. Mereka "TIDAK DIKETAHUI" dan dengan demikian satu nilai NULL dibandingkan dengan yang lain selalu salah. Melakukan perhitungan pada nilai NULL berakhir dengan hasil NULL. Cobalah untuk melihatnya dari perspektif nilai yang disebut UNKNOWN
Cine

Sebagai tipe number, NaNprimitif, dan karenanya secara unik ditentukan oleh nilainya.
Dmitri Zaitsev

4

NaNsingkatan Not a Number . Ini adalah nilai tipe data numerik (biasanya tipe floating point, tetapi tidak selalu) yang mewakili hasil operasi yang tidak valid seperti membagi dengan nol.

Meskipun namanya mengatakan itu bukan angka, tipe data yang digunakan untuk menyimpannya adalah tipe numerik. Jadi dalam JavaScript, meminta datatype NaNakan kembali number(seperti yang alert(typeof(NaN))ditunjukkan dengan jelas).


Sebenarnya pembagian dengan nol dievaluasi untuk InfinitytidakNaN
Dmitri Zaitsev

2

Javascript menggunakan NaN untuk mewakili apa pun yang dihadapinya yang tidak dapat direpresentasikan dengan cara lain dengan spesifikasinya. Itu tidak berarti itu bukan angka. Itu hanya cara termudah untuk menggambarkan pertemuan itu. NaN berarti bahwa itu atau objek yang merujuknya tidak dapat diwakili dengan cara lain dengan javascript. Untuk semua tujuan praktis, ini 'tidak dikenal'. Menjadi 'tidak dikenal' itu tidak bisa memberi tahu Anda apa itu atau bahkan jika itu sendiri. Bahkan bukan objek yang ditugaskan padanya. Ini hanya bisa memberi tahu Anda apa yang bukan, dan tidak ada atau tidak ada hanya dapat dijelaskan secara matematis dalam bahasa pemrograman. Karena matematika adalah tentang angka, javascript mewakili ketiadaan sebagai NaN. Itu tidak berarti itu bukan angka. Itu berarti kita tidak bisa membacanya dengan cara lain yang masuk akal. Itu sebabnya bisa ' bahkan tidak sama dengan dirinya sendiri. Karena tidak.


2

Nama yang lebih baik untuk NaN, menggambarkan maknanya lebih tepat dan kurang membingungkan, akan menjadi pengecualian numerik . Ini benar-benar jenis pengecualian objek lain yang menyamar sebagai memiliki tipe primitif (oleh desain bahasa), di mana pada saat yang sama ia tidak diperlakukan sebagai primitif dalam perbandingan diri yang salah. Dari mana kebingungan. Dan selama bahasa "tidak akan mengambil keputusan" untuk memilih antara objek pengecualian yang tepat dan bilangan primitif , kebingungan akan tetap ada.

Ketidaksamaan yang terkenal NaNitu sendiri, keduanya ==dan ===merupakan manifestasi dari desain yang membingungkan memaksa objek pengecualian ini menjadi tipe primitif. Ini mematahkan prinsip fundamental bahwa primitif secara unik ditentukan oleh nilainya . Jika NaNlebih disukai dilihat sebagai perkecualian (yang bisa ada jenisnya berbeda), maka itu tidak boleh "dijual" sebagai primitif. Dan jika ingin menjadi primitif, prinsip itu harus dipegang. Selama itu rusak, seperti yang kita miliki dalam JavaScript, dan kita tidak bisa benar-benar memutuskan di antara keduanya, kebingungan yang mengarah pada beban kognitif yang tidak perlu bagi semua orang yang terlibat akan tetap ada. Namun, yang sangat mudah diperbaiki dengan hanya membuat pilihan di antara keduanya:

  • baik membuat NaN objek pengecualian khusus yang berisi informasi berguna tentang bagaimana pengecualian muncul, sebagai lawan membuang informasi itu seperti apa yang saat ini diterapkan, yang mengarah ke kode yang lebih sulit untuk debug;
  • atau membuat NaNsuatu entitas dari tipe primitif number(yang bisa kurang membingungkan disebut "numerik"), dalam hal ini harus sama dengan dirinya sendiri dan tidak dapat berisi informasi lain; yang terakhir jelas merupakan pilihan yang lebih rendah.

Satu-satunya keuntungan dari memaksakan NaNke dalam numbertipe adalah dapat membuangnya kembali ke ekspresi numerik apa pun. Namun, yang membuatnya menjadi pilihan yang rapuh, karena hasil dari setiap ekspresi numerik yang mengandung NaNakan menjadi NaN, atau mengarah ke hasil yang tidak dapat diprediksi seperti NaN < 0mengevaluasi false, yaitu mengembalikanboolean alih-alih menjaga pengecualian.

Dan bahkan jika "segala sesuatunya seperti itu", tidak ada yang menghalangi kita untuk membuat perbedaan yang jelas untuk diri kita sendiri, untuk membantu membuat kode kita lebih mudah diprediksi dan lebih mudah disangkal. Dalam praktiknya, itu berarti mengidentifikasi pengecualian-pengecualian itu dan menanganinya sebagai pengecualian. Yang, sayangnya, berarti lebih banyak kode tetapi mudah-mudahan akan dikurangi dengan alat seperti TypeScript dari Flowtype.

Dan kemudian kita memiliki berantakan tenang vs berisik alias sinyal NaNperbedaan . Yang benar-benar adalah tentang bagaimana pengecualian ditangani, bukan pengecualian itu sendiri, dan tidak ada yang berbeda dari pengecualian lainnya.

Demikian pula, Infinitydan +Infinityelemen-elemen tipe numerik yang muncul dalam ekstensi garis nyata tetapi mereka bukan bilangan real. Secara matematis, mereka dapat diwakili oleh urutan bilangan real yang konvergen ke salah satu +atau -Infinity.


1

Ini hanya karena NaNmerupakan properti dari objek Number di JS, Ini tidak ada hubungannya dengan itu menjadi nomor.


Seperti setiap objek lainnya, Number dapat memiliki semua jenis properti. Number.fu = "bar"; alert(typeof Number.fu);
Alsciende

NaNbukan nilai yang disimpan Number.NaN, apa pun itu. NaNadalah nilai primitif dari tipe Number. Dan tambahannya, nilainya Number.NaNadalah NaN, tetapi itu tidak berhubungan.
Oriol

1

Cara terbaik untuk berpikir tentang NAN adalah tidak dikenal . Itulah mengapa NAN! = NAN karena setiap nilai NAN mewakili beberapa angka unik yang tidak dikenal. NAN diperlukan karena angka floating point memiliki rentang nilai yang terbatas. Dalam beberapa kasus pembulatan terjadi di mana bit yang lebih rendah hilang yang mengarah pada apa yang tampak seperti omong kosong seperti 1.0 / 11 * 11! = 1.0. Nilai yang benar-benar besar yang lebih besar adalah NAN dengan infinity sebagai contoh sempurna.

Mengingat kami hanya memiliki sepuluh jari, upaya apa pun untuk menunjukkan nilai yang lebih besar dari 10 adalah mustahil, yang berarti nilai tersebut harus berupa NAN karena kami telah kehilangan nilai sebenarnya dari nilai lebih besar dari 10 ini. Hal yang sama berlaku untuk nilai floating point, di mana nilainya melebihi batas dari apa yang dapat disimpan dalam float.


Infinity tidak diwakili oleh NaN. Mencoba mewakili angka di luar rentang akan dibulatkan ke bawah (ke max / -inf) atau ke atas (ke min / + inf).
OrangeDog


1

NaNadalah angka dari sudut pandang jenis, tetapi bukan angka normal seperti 1, 2 atau 329131. Nama "Bukan Angka" mengacu pada fakta bahwa nilai yang diwakili adalah spesial dan tentang domain spesifikasi format IEEE, bukan domain bahasa javascript.


1

Jika menggunakan jQuery, saya lebih suka isNumeric memeriksa jenis:

console.log($.isNumeric(NaN));  // returns false
console.log($.type(NaN));       // returns number

http://api.jquery.com/jQuery.isNumeric/


Terima kasih sobat. Saya punya masalah dengan isNumberdari utilpaket naskah. Bagus bahwa kami masih menggunakan jQueryproyek kami jadi gunakan saran Anda sebagai gantinya.
Ashok MA

Untuk rec, isNumberdari utilnaskah juga kembali trueuntuk NaN.
Ashok MA

0

Javascript hanya memiliki satu tipe data numerik, yang merupakan float presisi ganda 64-bit standar. Semuanya ganda. NaN adalah nilai spesial ganda, tetapi tetap ganda.

Yang perlu parseIntdilakukan hanyalah "membuang" string Anda ke dalam tipe data numerik, sehingga hasilnya selalu "angka"; hanya jika string asli tidak dapat diuraikan, nilainya akan menjadi NaN.


0

NaN masih merupakan tipe numerik, tetapi itu mewakili nilai yang tidak bisa mewakili angka yang valid.


0

Kita dapat berargumen bahwa NaN adalah objek kasus khusus. Dalam hal ini, objek NaN mewakili angka yang tidak masuk akal secara matematis. Ada beberapa objek kasus khusus lainnya dalam matematika seperti INFINITE dan sebagainya.

Anda masih dapat melakukan beberapa perhitungan dengan itu, tetapi itu akan menghasilkan perilaku aneh.

Info lebih lanjut di sini: http://www.concentric.net/~ttwang/tech/javafloat.htm (berbasis java, bukan javascript)


0

Anda harus menyukai Javascript. Ini memiliki beberapa kebiasaan kecil yang menarik.

http://wtfjs.com/page/13

Sebagian besar kebiasaan itu dapat dijelaskan jika Anda berhenti mengerjakannya secara logis, atau jika Anda tahu sedikit tentang teori bilangan, tetapi mereka tetap bisa menangkap Anda jika Anda tidak mengetahuinya.

Ngomong-ngomong, saya sarankan membaca sisa http://wtfjs.com/ - ada banyak kebiasaan yang lebih menarik daripada yang ditemukan!


0

Nilai NaN adalah benar-benar Number.NaN maka ketika Anda bertanya apakah itu nomor itu akan mengatakan ya. Anda melakukan hal yang benar dengan menggunakan panggilan isNaN ().

Sebagai informasi, NaN juga dapat dikembalikan oleh operasi pada Numbers yang tidak didefinisikan seperti divisi dengan nol atau akar kuadrat dari angka negatif.


Dalam arti apa itu "nilai"? NaN == Number.NaNmengevaluasi ke false!
Dmitri Zaitsev

@DmitriZaitsev Sudahkah Anda membaca utasnya? Dan sudahkah Anda mencoba if (parseInt ("nan") == Number.NaN)? Coba juga! = Dan lihat apa yang diceritakannya kepada Anda.
Rob

Maaf, lupa NaN==NaNmakhluk bodoh itu false, pastilah sadis yang menemukan itu untuk membuat semua orang menderita.
Dmitri Zaitsev

0

Sebuah contoh

Bayangkan Kami mengonversi string ke angka:

Number("string"); // returns NaN

Kami mengubah tipe data menjadi angka tetapi nilainya bukan angka!


Anda sepertinya telah melewatkan inti pertanyaan. NaNadalah dari jenis nomor . Pertanyaannya adalah bertanya mengapa.
Quentin

@ Quentin saya jelaskan di baris terakhir.
Amir Fo

-1

Ini adalah nilai khusus tipe Angka sebagai POSITIVE_INFINITY

Mengapa? Dengan desain

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.