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 : n
f(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 : -n
ve bir in hesaplama dahil unchecked
blokta. Sonra Int.Min
da 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
, n
bir 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)) = -n
ardışık iki olumsuz uygulamasıdır f
. Diğer f
dö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^32
dö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 => x
bunu izlediği için 0 => x => 0 => x
. Bu sadece iki uzunluklu bir döngüdür ve x
iki uygulamadan sonra kendi içine dönüşür, içine dönüşmez -x
. Neyse ki sorunu çözen bir vaka var. Eğer X
eş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^32
sıfır bırakarak sabit bir nokta, sayıları 2^32 - 1
sayı 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 -4
iç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, +4
3 bit tam sayı olarak gösterilememesidir. Biz elde ediyorum +4
olumsuzlaştırılmasıyla -3
için +3
hala geçerli 3 bitlik tamsayı nedir - - ama sonra bir eklenerek +3
(ikili 011
) verir 100
ikili. İşaretsiz tam sayı olarak yorumlanır, +4
ancak işaretli tam sayı olarak yorumlamamız gerekir -4
. Yani aslında -4
bu örnek için veya Int.MinValue
genel durumda tamsayı aritmetik olumsuzlamanın ikinci bir sabit noktasıdır - 0
ve Int.MinValue
kendileriyle 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 +3
olarak döngüye girer -4
. Sonuç olarak -4
, iki işlev uygulamasından sonra +3
doğru şekilde eşlenir, -3
iki işlev uygulamasından sonra doğru olarak eşlenir , ancak -3
iki 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 0
ve Int.MinValue
kendileri ve iki rastgele tamsayı x
ile eşlenmelidir ve -x
bu iki işlev uygulaması tarafından birbirine eşlenmelidir.
Eşlemek için x
için -x
ve 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 0
ve Int.MinValue
de karşıt köşeleri olması gerekir. Bu , iki sabit noktayı ve iki işlev uygulamasından sonra doğru bir şekilde eşler x
ve -x
değ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.0
Int.MinValue