Ini berlaku untuk semua angka negatif.
f (n) = abs (n)
Karena ada satu angka lebih negatif daripada angka positif untuk dua integer komplemen, f(n) = abs(n)valid untuk satu kasus lebih dari f(n) = n > 0 ? -n : nsolusi yang sama dengan f(n) = -abs(n). Punya satu per satu ...: D
MEMPERBARUI
Tidak, itu tidak berlaku untuk satu kasus lagi karena saya baru saja dikenali oleh komentar litb ... abs(Int.Min)hanya akan meluap ...
Saya berpikir tentang menggunakan informasi mod 2 juga, tetapi menyimpulkan, itu tidak berfungsi ... untuk awal. Jika dilakukan dengan benar, ini akan berfungsi untuk semua angka kecuali Int.Minkarena ini akan meluap.
MEMPERBARUI
Saya bermain dengannya sebentar, mencari trik manipulasi bit yang bagus, tetapi saya tidak dapat menemukan satu-liner yang bagus, sedangkan solusi mod 2 cocok untuk satu.
f (n) = 2n (abs (n)% 2) - n + sgn (n)
Di C #, ini menjadi yang berikut:
public static Int32 f(Int32 n)
{
return 2 * n * (Math.Abs(n) % 2) - n + Math.Sign(n);
}
Untuk membuatnya berfungsi untuk semua nilai, Anda harus mengganti Math.Abs()dengan (n > 0) ? +n : -ndan memasukkan perhitungan dalam satu uncheckedblok. Kemudian Anda bahkan Int.Mindipetakan ke dirinya sendiri seperti halnya negasi yang tidak terkendali.
MEMPERBARUI
Terinspirasi oleh jawaban lain saya akan menjelaskan bagaimana fungsi bekerja dan bagaimana membangun fungsi seperti itu.
Mari kita mulai dari awal. Fungsi fini berulang kali diterapkan pada nilai yang diberikan nmenghasilkan urutan nilai.
n => f (n) => f (f (n)) => f (f (f (n)))) => f (f (f (f (f (n)))))) => ...
Pertanyaannya menuntut f(f(n)) = -n, yaitu dua aplikasi berturut-turut fmeniadakan argumen. Dua aplikasi lebih lanjut dari f- total empat - meniadakan argumen lagi menghasilkan nlagi.
n => f (n) => -n => f (f (f (n))) => n => f (n) => ...
Sekarang ada siklus panjang empat yang jelas. Mengganti x = f(n)dan mencatat bahwa persamaan yang diperoleh f(f(f(n))) = f(f(x)) = -xberlaku, menghasilkan yang berikut.
n => x => -n => -x => n => ...
Jadi kita mendapatkan siklus panjang empat dengan dua angka dan dua angka dinegasikan. Jika Anda membayangkan siklus sebagai persegi panjang, nilai yang dinegasikan terletak di sudut yang berlawanan.
Salah satu solusi untuk membangun siklus seperti itu adalah yang berikut dimulai dari n.
n => meniadakan dan kurangi satu
-n - 1 = - (n +1) => tambahkan satu
-n => negate dan tambahkan satu
n +1 => kurangi satu
n
Contoh konkret dari siklus semacam itu adalah +1 => -2 => -1 => +2 => +1. Kami hampir selesai. Memperhatikan bahwa siklus yang dikonstruksi mengandung bilangan positif ganjil, bahkan penggantinya, dan kedua bilangan tersebut meniadakan, kita dapat dengan mudah mempartisi bilangan bulat menjadi banyak siklus semacam itu ( 2^32merupakan kelipatan empat) dan telah menemukan fungsi yang memenuhi kondisi.
Tetapi kami memiliki masalah dengan nol. Siklus harus mengandung 0 => x => 0karena nol dinegasikan ke dirinya sendiri. Dan karena siklus menyatakan sudah 0 => xmengikuti 0 => x => 0 => x. Ini hanya siklus panjang dua dan xdiubah menjadi dirinya sendiri setelah dua aplikasi, bukan menjadi -x. Untungnya ada satu kasus yang menyelesaikan masalah. Jika Xsama dengan nol kita memperoleh siklus panjang yang hanya mengandung nol dan kita memecahkan masalah itu dengan menyimpulkan bahwa nol adalah titik tetap f.
Selesai? Hampir. Kami memiliki 2^32angka, nol adalah angka tetap yang meninggalkan titik 2^32 - 1, dan kami harus mempartisi angka itu menjadi siklus empat angka. Buruk itu 2^32 - 1bukan kelipatan empat - akan tetap ada tiga angka tidak dalam siklus dengan panjang empat.
Saya akan menjelaskan bagian yang tersisa dari solusi menggunakan set yang lebih kecil dari 3 bit yang ditandatangani mulai dari -4ke +3. Kita selesai dengan nol. Kami memiliki satu siklus lengkap +1 => -2 => -1 => +2 => +1. Sekarang mari kita buat siklus mulai dari +3.
+3 => -4 => -3 => +4 => +3
Masalah yang muncul adalah yang +4tidak direpresentasikan sebagai integer 3 bit. Kami akan memperoleh +4dengan meniadakan -3ke +3- apa yang masih merupakan integer 3 bit yang valid - tetapi kemudian menambahkan satu ke +3(biner 011) menghasilkan 100biner. Ditafsirkan sebagai bilangan bulat yang tidak ditandatangani, +4tetapi kita harus menafsirkannya sebagai bilangan bulat yang ditandatangani -4. Jadi sebenarnya -4untuk contoh ini atau Int.MinValuedalam kasus umum adalah titik tetap kedua negasi aritmatika bilangan bulat - 0 dan Int.MinValuedipetakan ke mereka sendiri. Jadi siklusnya sebenarnya sebagai berikut.
+3 => -4 => -3 => -4 => -3
Ini adalah siklus dengan panjang dua dan juga +3memasuki siklus melalui -4. Karena -4itu dipetakan dengan benar ke dirinya sendiri setelah dua aplikasi fungsi, +3dipetakan dengan benar ke -3setelah dua aplikasi fungsi, tetapi -3dipetakan secara keliru ke dirinya sendiri setelah dua aplikasi fungsi.
Jadi kami membangun fungsi yang bekerja untuk semua bilangan bulat kecuali satu. Bisakah kita berbuat lebih baik? Tidak, kita tidak bisa. Mengapa? Kita harus membuat siklus dengan panjang empat dan mampu mencakup seluruh rentang integer hingga empat nilai. Nilai yang tersisa adalah dua titik tetap 0dan Int.MinValueyang harus dipetakan untuk diri mereka sendiri dan dua bilangan bulat sewenang-wenang xdan -xyang harus dipetakan satu sama lain oleh dua aplikasi fungsi.
Untuk memetakan xke -xdan sebaliknya mereka harus membentuk empat siklus dan mereka harus berada di sudut yang berlawanan dari siklus itu. Karena itu 0dan Int.MinValueharus berada di sudut yang berlawanan juga. Ini akan memetakan dengan benar xdan -xtetapi menukar dua titik tetap 0dan Int.MinValuesetelah dua aplikasi fungsi dan meninggalkan kita dengan dua input yang gagal. Jadi tidak mungkin untuk membangun fungsi yang bekerja untuk semua nilai, tetapi kami memiliki satu yang berfungsi untuk semua nilai kecuali satu dan ini adalah yang terbaik yang bisa kami capai.