NaN mungkin masih sedikit mengejutkan Anda

gambar



Awalnya, saya pikir ini hanya pertanyaan lain yang mungkin ditanyakan dalam sebuah wawancara. Mungkin, jika Anda menggunakan otak Anda dengan benar, Anda bisa menebak apa hasilnya. Bersandar di kursinya, dia mulai berpikir, menghidupkan logika, mengingat sesuatu yang dapat diandalkan dalam penalaran. Tapi sia-sia! Tiba-tiba menjadi sangat jelas bahwa jawabannya tidak dapat ditemukan. Tapi kenapa? Apa yang perlu Anda pahami untuk menemukannya? Dalam matematika? Dalam bahasa pemrograman?



Jawabannya harus NaN. Tetapi mengapa saya tidak yakin tentang ini? Sepanjang jalan, saya yakin bahwa ekspresi apa pun yang mengandung NaN akan mengembalikan NaN. Yah, mungkin hanya jika Anda membagi NaN dengan nol - dalam kasus ini, pengecualian ZeroDivisionError akan ditampilkan . Seratus persen NaN!



Saya memasukkan ekspresi ke dalam sel notepad:



>>> 1**nan + 1**nan
2.0


Memang? Tunggu:



>>> arange(5)**nan
array([nan,  1., nan, nan, nan])


Artinya, untuk beberapa alasan, satu pangkat NaN adalah satu, tetapi nol dan semua bilangan lain pangkat NaN adalah NaN. Dimana logikanya? Apa masalahnya?



Jadi ayo pergi lagi:



>>> 0**nan, 1**nan
(nan, 1.0)


Mungkin saya hanya tidak curiga karena kurangnya kebutuhan praktis untuk pengetahuan yang mendalam tentang NaN? Atau mungkin aku tahu, tapi lupa? Atau mungkin lebih buruk - saya tidak tahu dan lupa?



Kami pergi ke Wikipedia . Di sana, masalah ini juga ditetapkan sebagai masalah, tetapi mengapa semuanya diatur seperti ini tidak dijelaskan dengan cara apa pun. Tapi saya belajar bahwa:



>>> hypot(inf, nan)
inf


Meski, pada saat bersamaan:



>>> sqrt(inf**2 + nan**2)
nan


Itu, Anda tahu, juga agak aneh.



Oke, dari Wikipedia kita pergi ke C99 di halaman 182 dan akhirnya mendapatkan penjelasan logis mengapa pow (x, 0) mengembalikan 1 untuk x apa pun , bahkan untuk x sama dengan NaN:



>>> power(nan, 0)
1.0


Jika fungsinya f(x) diangkat ke kekuasaan g(x) dan dimana g(x) cenderung 0, maka hasilnya akan menjadi 1, apa pun nilainya f(x)...



gambar



Dan jika hasilnya tidak tergantung pada nilai numerik fungsinyaf(x), maka 1 adalah hasil yang valid, bahkan untuk NaN. Namun, ini masih tidak menjelaskan mengapa 1 pangkat NaN adalah 1. Kami



mencari C99 lain dan di halaman 461 kami tidak melihat penjelasan, hanya persyaratan bahwa pow (+1, y) harus mengembalikan 1 untuk semua y , genap sama NaN. Segala sesuatu.



Di sisi lain, menjelaskan mengapa pow (NaN, 0) = 1 lebih disukai daripada pow (NaN, 0) = NaN masih menunjukkan bahwa NaN tidak boleh dianggap secara harfiah sebagai Not-a-Number ... Misalkan, sebagai hasil dari beberapa perhitungan, kami mendapatkan angka yang melebihi ukuran memori yang dialokasikan untuk jenis angka ini, misalnya:



>>> a = pi*10e307
>>> a
inf


Hasilnya, kami mendapat inf , angka apa sebenarnya yang kami tidak tahu, tapi tetap saja itu semacam angka. Kemudian kami menghitung sesuatu lagi dan lagi mendapatkan angka yang terlalu besar:

>>> b = e*10e307
>>> b
inf


Perbedaan antara a dan b akan mengembalikan NaN:



>>> c = a - b
>>> c
nan


Satu-satunya alasan kita dapat menganggap c bukan angka adalah karena kita tidak menggunakan perhitungan yang akurat. Namun, di c, di bawah NaN, masih ada makna yang tersembunyi. Kami tidak tahu apa artinya ini. Tetapi ini tetap angka, dan karena ini adalah angka, maka tidak mengherankan jika pow (1, NaN) = 1 .



Lalu mengapa pow (0, NaN) = NaN ? Faktanya adalah jika kita menaikkan 0 pangkat apa pun, maka kita benar-benar mendapatkan nol. Kecuali untuk satu kasus - jika derajatnya 0:



>>> 0**0
1


Oleh karena itu , terdapat ambiguitas pada ekspresi pow (0, NaN) dengan nilai NaN tertentu. Tentu saja, probabilitas bahwa 0 dapat disembunyikan di bawah NaN semakin kecil, dan orang dapat berasumsi bahwa pow (0, NaN) = 0 . Tapi masih lebih baik untuk bermain aman, Anda tidak pernah tahu apa yang bisa terjadi. Mungkin begitulah alasan mereka ketika standar dibuat.



Saya bahkan tidak tahu harus berkata apa lagi ... jika Anda tahu jawabannya sebelumnya, kemungkinan besar Anda bisa iri, karena bidang di mana pengetahuan semacam itu bisa berguna mungkin penuh dengan tugas-tugas yang menarik. Dan mungkin sebaliknya. Tulislah di kolom komentar.



PS Karena NaN mengacu pada angka floating point, ini bisa menjadi kunci kamus:



>>> d = {0.1: 'a', nan: 'b'}
>>> d[nan]
'b'


Apakah masuk akal untuk menggunakan ini dalam praktik? Saya tidak berpikir itu sepadan.



All Articles