Dapatkah operator matematika *, /, +, -, ^ digunakan untuk mengonversi bilangan bukan nol menjadi 1?

118

Saya bekerja dengan perangkat lunak (Oracle Siebel) yang hanya mendukung ekspresi JavaScript dengan operator multiply, membagi, mengurangi, menambah, dan XOR ( *, /, -, +, ^). Saya tidak memiliki operator lain seperti !atau ? :tersedia.

Dengan menggunakan operator di atas, apakah mungkin untuk mengonversi angka menjadi 1 jika bukan nol dan membiarkannya 0 jika sudah nol? Angka tersebut bisa positif, nol, atau negatif.

Contoh:

var c = 55;

var d;  // d needs to set as 1

Saya mencoba c / c, tetapi mengevaluasi NaNkapan c0. dperlu 0 saat c0.

c adalah nilai mata uang, dan akan memiliki maksimal dua digit terakhir dan 12 digit awal.

Saya mencoba meniru ifkondisi dengan mengubah angka menjadi Boolean 0 atau 1, lalu mengalikan bagian lain dari ekspresi.

dave
sumber
3
Komentar tidak untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan .
Samuel Liew
10
@SamuelLew Meski komentarnya banyak, dan ada yang harus dihilangkan ( diskusi , jawab di komentar ), kebanyakan memang meminta klarifikasi ( misalnya ). Komentar yang menanyakan apakah itu masalah XY adalah batas.
pengguna202729
Operator Numerik Oracle Siebel, tampaknya merupakan Eksponen: docs.oracle.com/cd/E95904_01/books/VBLANG/…
Derrick Moeller
2
@DerrickMoeller Tampaknya ada perbedaan antara Siebel VB dan Siebel eScript. Yang terakhir, ini adalah xor bitwise . Saya tidak yakin yang mana dari keduanya yang berlaku di sini.
CRice
3
@ user202729 setelah seluruh utas komentar menjadi terlalu panjang, kita tidak akan memperlakukan komentar secara berbeda, karena antarmuka mod yang dibuat oleh admin SE / devs lebih memilih tindakan default kita menjadi "pindah ke obrolan" atau "hapus semua". Jika ada komentar yang berguna, itu harus diedit menjadi pertanyaan itu sendiri atau diposting sebagai jawaban. Jika ada komentar di luar topik, komentar tersebut seharusnya sudah dipangkas / dihapus sendiri. Jika Anda ingin mendiskusikan "fitur" mod ini dan / atau "terlalu banyak komentar" yang didapat moderator bendera otomatis, harap bahas untuk diskusi di Meta atau Meta.SE. Terima kasih.
Samuel Liew

Jawaban:

149

c / (c + 5e-324)harus bekerja. (Konstanta 5e-324adalah Number.MIN_VALUE, bilangan positif terkecil yang dapat direpresentasikan.) Jika x adalah 0, itu persis 0, dan jika x bukan nol (secara teknis, jika x setidaknya 4.45014771701440252e-308, yang merupakan bilangan bukan nol terkecil yang diizinkan di pertanyaan, 0,01, adalah), matematika floating-point JavaScript terlalu tidak tepat untuk jawabannya menjadi berbeda dari 1, jadi akan keluar persis 1.

Joseph Sible-Reinstate Monica
sumber
1
Anda perlu mengubah ekspresi menjadi bool terlebih dahulu, karena OP mencoba mengalikan 0 dan 1 dengan other parts of the expression, dan c / (c + 5e-324) * some_expressiontidak akan berhasil
phuclv
28
Mengambil bug dan mengubahnya menjadi fitur di sana
Chirag Bhatia - chirag64
1
@Medinoc ya, tapi pertanyaannya juga mengatakan bahwa tidak akan pernah ada lebih dari 2 digit setelah koma desimal, dan 324 lebih dari 2.
Joseph Sible-Reinstate Monica
1
Ini menarik dan mungkin berhasil untuk OP, tetapi saya benar-benar benci menemukan kode semacam ini saat bekerja dalam tim. Paling tidak, itu harus didokumentasikan dan diuji dengan baik.
Eric Duminil
1
@JosephSible Saya tahu, tetapi jika Anda benar-benar menganggapnya seperti itu, jawaban yang paling jelas adalah Number(Boolean(n)), yang tidak menggunakan operator. Saya tidak mengatakan ini bukan jawaban yang dicari OP, tapi ini bukan jawaban atas pertanyaan yang dijelaskan OP. Mungkin harus memperbaiki pertanyaan itu.
pengguna5532169
216

Gunakan ekspresi tersebut n/n^0.

Jika nbukan nol:

 Step    Explanation
------- -------------------------------------------------------------------------------
 n/n^0   Original expression.
 1^0     Any number divided by itself equals 1. Therefore n/n becomes 1.
 1       1 xor 0 equals 1.

Jika nnol:

 Step    Explanation
------- -------------------------------------------------------------------------------
 n/n^0   Original expression.
 0/0^0   Since n is 0, n/n is 0/0.
 NaN^0   Zero divided by zero is mathematically undefined. Therefore 0/0 becomes NaN.
 0^0     In JavaScript, before any bitwise operation occurs, both operands are normalized.
         This means NaN becomes 0.
 0       0 xor 0 equals 0.

Seperti yang Anda lihat, semua nilai bukan nol diubah menjadi 1, dan 0 tetap berada di 0. Ini memanfaatkan fakta bahwa dalam JavaScript, NaN^0adalah 0.

Demo:

[0, 1, 19575, -1].forEach(n => console.log(`${n} becomes ${n/n^0}.`))

CRice
sumber
45
TIL: Number.NaN ^ n === no_O (di mana nadalah bilangan terbatas)
zerkms
17
Tampaknya ketika digunakan sebagai operan bitwise, dengan NaNmudah diubah menjadi nol. Lihat: Operasi bitwise pada bukan angka
CRice
3
@zerkms Mungkin ~~NaN === 0tampak lebih alami
Bergi
8
@EnricoBorba Ini bukan eksponensiasi (yang menggunakan **), ini XOR bitwise. Operasi bitwise memiliki prioritas yang sangat rendah di javascript sehingga pembagian akan terjadi terlebih dahulu.
CRice
3
^adalah operator bitwise xor. Saya ragu jika ^di OP adalah xor bitwise bila semua operator lain adalah operator aritmatika. Ini mungkin operator eksponen ( **dalam JavaScript).
Salman A
17

(((c/c)^c) - c) * (((c/c)^c) - c) akan selalu mengembalikan 1 untuk negatif dan positif dan 0 untuk 0.

Ini pasti lebih membingungkan daripada jawaban yang dipilih dan lebih lama. Namun, saya merasa ini kurang hacky dan tidak mengandalkan konstanta.

EDIT: Seperti yang disebutkan @JosephSible, versi saya yang lebih ringkas dan versi @ CRice yang tidak menggunakan konstanta adalah:

c/c^c-c
Kyle Wardle
sumber
Jawaban CRice tidak dipilih, Joseph Sible dipilih. Sejujurnya saya tidak memperhatikan jawaban CRice sampai setelah posting.
Kyle Wardle
2
Ia tidak menggunakan konstanta, hanya operator dan variabel yang diberikan.
L3viathan
2
@JosephSible c/c^(c-c)hanyac
Tavian Barnes
2
@JosephSible Saya membaca ^sebagai eksponen seperti yang tersirat oleh OP "mengalikan, membagi, mengurangi, menambah, dan eksponen (*, /, -, +, ^ )". Jika ^XOR dengan JavaScript diutamakan maka saya salah. Saya meminta klarifikasi tentang OP.
Tavian Barnes
2
@TavianBarnes bukan itu yang ditulis OP; seseorang mengedit pertanyaan itu. Saya mengembalikannya ke cara OP sebenarnya bertanya.
Joseph Sible-Reinstate Monica
2

Jawaban yang sangat rumit, tetapi tidak bergantung pada presisi terbatas: Jika Anda mengambilnya x^(2**n), ini akan selalu sama dengan x+2**njika x adalah nol, tetapi akan sama dengan x-2**njika x memiliki satu di tempat ke-n. Jadi, untuk x = 0, (x^(2**n)-x+2**n)/(2**(n+1)akan selalu 1, tetapi terkadang nol untuk x! = 0. Jadi jika Anda mengambil hasil perkalian dari (x^(2**n)-x+2**n)/(2**(n+1)semua n, maka XOR dengan 1, Anda akan mendapatkan fungsi yang Anda inginkan. Anda harus mengkodekan setiap faktor secara manual. Dan Anda harus memodifikasi ini jika Anda menggunakan floating point.

Jika Anda memiliki ==operator, maka (x==0)^1berfungsi.

Akumulasi
sumber
3
Tidak ada **juga ==tidak tersedia.
Joseph Sible-Reinstate Monica