Bu, tüm negatif sayılar için geçerlidir.
f (n) = abs (n)
İki tamamlayıcı tamsayı için pozitif sayılardan bir tane daha negatif sayı olduğu için , aynı ile aynı çözümden f(n) = abs(n)bir tane daha durum için geçerlidir . Birini yakaladım ...: Df(n) = n > 0 ? -n : nf(n) = -abs(n)
GÜNCELLEME
Hayır, sadece bir durum için geçerli değil çünkü az önce litb'nin yorumuyla tanıştım ... abs(Int.Min)sadece taşacak ...
Ben de mod 2 bilgilerini kullanmayı düşündüm, ama sonuçta, işe yaramadı ... erken. Doğru yapılırsa Int.Min, taşması dışında tüm sayılar için çalışır .
GÜNCELLEME
Bir süre onunla oynadım, güzel bir manipülasyon hilesi arıyorum, ancak mod 2 çözümü bir tanesine uyurken güzel bir tek astar bulamadım.
f (n) = 2n (abs (n)% 2) - n + sgn (n)
C # 'da bu şu olur:
public static Int32 f(Int32 n)
{
return 2 * n * (Math.Abs(n) % 2) - n + Math.Sign(n);
}
Tüm değerler için çalışan almak için, değiştirmek zorunda Math.Abs()olan (n > 0) ? +n : -nve bir in hesaplama dahil uncheckedblokta. Sonra Int.Minda kontrolsüz olumsuzlama gibi kendi kendine haritalanır.
GÜNCELLEME
Başka bir cevaptan esinlenerek işlevin nasıl çalıştığını ve böyle bir işlevi nasıl oluşturacağınızı açıklayacağım.
En baştan başlayalım. Fonksiyon f, nbir dizi değer veren belirli bir değere tekrar tekrar uygulanır .
n => f (n) => f (f (n)) => f (f (f (n))) => f (f (f (f (n))))) => ...
Soru , argümanın f(f(n)) = -nardışık iki olumsuz uygulamasıdır f. Diğer fdört uygulama - toplamda dört - tekrar ortaya çıkan argümanı yeniden reddetmektedir n.
n => f (n) => -n => f (f (f (n))) => n => f (n) => ...
Şimdi dört uzunluklu bariz bir döngü var. x = f(n)Elde edilen denklemin ikame edilmesi ve tutulması f(f(f(n))) = f(f(x)) = -x, aşağıdakileri verir.
n => x => -n => -x => n => ...
Böylece iki sayı ve dört sayı ile birlikte dört uzunluklu bir döngü elde ederiz. Döngüyü dikdörtgen olarak hayal ediyorsanız, reddedilen değerler karşıt köşelerde bulunur.
Böyle bir döngü oluşturmak için birçok çözümden biri, n'den başlayarak aşağıdakilerdir.
n => birini reddet ve çıkar
-n - 1 = - (n + 1) => bir tane ekle
-n => olumsuzlama ve bir tane ekleme
n + 1 => birini çıkart
n
Somut bir örnek böyle bir döngüdür +1 => -2 => -1 => +2 => +1. Neredeyse bitti. İnşa edilen döngünün tek bir pozitif sayı içerdiğini, hatta ardılı olduğunu ve her iki sayı da olumsuzladığını belirterek, tam sayıları bu tür döngülere kolayca bölebiliriz ( 2^32dördün katıdır) ve koşulları sağlayan bir işlev bulduk.
Ama sıfırla ilgili bir sorunumuz var. Döngü içermelidir 0 => x => 0çünkü sıfır kendi kendine reddedilir. Ve döngü halihazırda 0 => xbunu izlediği için 0 => x => 0 => x. Bu sadece iki uzunluklu bir döngüdür ve xiki uygulamadan sonra kendi içine dönüşür, içine dönüşmez -x. Neyse ki sorunu çözen bir vaka var. Eğer Xeşittir sıfır biz sadece sıfır içeren tek üyeli bir döngü elde etmek ve sıfır sabit nokta olduğunu biz bu sorun YAPILMASINA çözüldü f.
Bitti? Neredeyse. Biz 2^32sıfır bırakarak sabit bir nokta, sayıları 2^32 - 1sayı ve dört sayı döngü içine bu numarayı bölüm gerekmektedir. Kötü 2^32 - 1, dördün katı değildir - dört uzunluktaki herhangi bir döngüde olmayan üç sayı kalır.
Ben arasında değişen 3 bitlik imzalı itegers küçük kümesi kullanılarak çözeltinin geri kalan kısmını açıklayacağız -4için +3. Sıfırla işimiz bitti. Bir tam döngümüz var +1 => -2 => -1 => +2 => +1. Şimdi bize döngüsü başlayan inşa edelim +3.
+3 => -4 => -3 => +4 => +3
Ortaya çıkan sorun, +43 bit tam sayı olarak gösterilememesidir. Biz elde ediyorum +4olumsuzlaştırılmasıyla -3için +3hala geçerli 3 bitlik tamsayı nedir - - ama sonra bir eklenerek +3(ikili 011) verir 100ikili. İşaretsiz tam sayı olarak yorumlanır, +4ancak işaretli tam sayı olarak yorumlamamız gerekir -4. Yani aslında -4bu örnek için veya Int.MinValuegenel durumda tamsayı aritmetik olumsuzlamanın ikinci bir sabit noktasıdır - 0 ve Int.MinValuekendileriyle eşleştirilir. Yani döngü aslında aşağıdaki gibidir.
+3 => -4 => -3 => -4 => -3
Bu iki uzunluklu bir döngüdür ve ek +3olarak döngüye girer -4. Sonuç olarak -4, iki işlev uygulamasından sonra +3doğru şekilde eşlenir, -3iki işlev uygulamasından sonra doğru olarak eşlenir , ancak -3iki işlev uygulamasından sonra hatalı olarak eşlenir.
Bu yüzden biri hariç tüm tamsayılar için çalışan bir fonksiyon oluşturduk. Daha iyisini yapabilir miyiz? Hayır yapamayız. Neden? Dört uzunluktaki döngüleri inşa etmeliyiz ve dört değere kadar tam sayı aralığını kapsayabiliriz. Kalan değerler iki sabit noktadır 0ve Int.MinValuekendileri ve iki rastgele tamsayı xile eşlenmelidir ve -xbu iki işlev uygulaması tarafından birbirine eşlenmelidir.
Eşlemek için xiçin -xve ters bir dört devir oluşturmak içermesi ve bu döngü zıt köşelerinde yer almalıdır tam tersi. Sonuç olarak 0ve Int.MinValuede karşıt köşeleri olması gerekir. Bu , iki sabit noktayı ve iki işlev uygulamasından sonra doğru bir şekilde eşler xve -xdeğiştirir ve bizi iki hatalı girişle bırakır. Bu nedenle, tüm değerler için çalışan bir işlev oluşturmak mümkün değildir, ancak biri hariç tüm değerler için çalışan bir işlevimiz vardır ve bu elde edebileceğimiz en iyisidir.0Int.MinValue