Konwertuj liczbę dodatnią na ujemną w C #


142

Możesz przekonwertować liczbę ujemną na dodatnią w następujący sposób:

int myInt = System.Math.Abs(-5);

Czy istnieje równoważna metoda zmiany liczby dodatniej na ujemną?



3
280Z28: To jest równoważne z myInt = -1.
rekurencyjny

1
musi być myInt | = int.MinValue;
Charles Bretana

@ 280Z28: To działa tylko dla liczb nieparzystych, w przeciwnym razie jest to to samo, co uczynienie liczby ujemną, a następnie odjęcie 1.
Cecil ma imię

3
Dla przejrzystości kodu nie sądzę, abyś używał System.Math.Abs ​​(), jeśli chcesz po prostu „przekonwertować liczbę ujemną na dodatnią”. Matematycznie nie jest to wartość bezwzględna, mimo że uzyskuje się pożądany rezultat. W zależności od kontekstu algorytmicznego, powinieneś użyć rozwiązania, które zaakceptowałeś poniżej, aby przejść od negatywnego do pozytywnego.
Chris Dwyer

Odpowiedzi:


452

Co powiesz na

myInt = myInt * -1


55
To rozwiązanie jest świetne, ponieważ może również konwertować negatywne na pozytywne! Geniusz!
Will Eddins

19
Wydawało mi się, że można po prostu umieścić znak „-” przed czymkolwiek, aby to zanegować ... -myInt To byłby minus wartości w myInt ... -ABS (myInt) byłby zabezpieczonym minusem.
DataDink

12
o czym myInt = - Myint?
kokbira

9
czy nawet krócej myInt *= - 1?
nawfal

FYI, jeśli spróbujesz metody Kokbiry z krótkim, myShort = (short) -myShortrzut jest konieczny, ponieważ krótka staje się int, gdy jest zanegowana.
AaronLS

236
int myNegInt = System.Math.Abs(myNumber) * (-1);

29
+1 za zapamiętanie, że jeśli jest już negatywem, miałbyś odwrotny skutek. Twoja odpowiedź jest jedyną, która zawsze daje liczbę ujemną, niezależnie od tego, czy myNumber jest dodatnia czy ujemna.
David

Masz tylko 26 głosów na tę odpowiedź? Czy są użytkownicy SO, którzy uważają, że to nie zadziała?
MusiGenesis

6
30 głosów pozytywnych? Już pytanie jest takie proste. A ta zbyt skomplikowana odpowiedź (wystarczyłaby również -System.Math.Abs ​​(myNumber)) daje 30 głosów w górę ????
mmmmmmmm

4
@rstevens wszyscy wspólnie próbujący wskazać, że ta odpowiedź jest znacznie bardziej poprawna niż zaakceptowana. Ponadto - vs * -1 zdecydowanie nie jest „przesadnie skomplikowane”.
Rex M

4
Ta odpowiedź podoba mi się bardziej niż -System.Math.Abs ​​jeden, ponieważ na pierwszy rzut oka jest trochę bardziej oczywiste, co się dzieje ... Myślę, że byłoby nieco łatwiej przeoczyć „-” przed stwierdzeniem.
Beska

132
int negInt = -System.Math.Abs(myInt)

11
Tak, ponieważ celem jest negacja, więc jednoargumentowy minus jest właściwym operatorem. Z drugiej strony mnożenie przez minus to tylko trik mający na celu zanegowanie wartości.
Steven Sudit

38
To sztuczka, ponieważ liczy się efekt uboczny, a nie główny. Podstawowym skutkiem jednoargumentowego minus jest negacja. Podstawowym efektem pomnażania jest rozmnażanie. Tak się składa, że ​​pomnożenie przez -1 jest negacją. Czy to jest jaśniejsze?
Steven Sudit

5
@StevenSudit Nie, nie ładniej niż * -1. Mnożenie przez -1 nie jest „sztuczką”, jest to matematyczny sposób zmiany liczby na ujemną. -Number to po prostu skrót -1 * Number. Ponadto używanie Abs do utrzymywania ujemnej liczby jest przesadą. myInt<0 ? myInt : -myInt;jest znacznie lepsza. Tylko dlatego, że operator - jest podany jako skrót dla właściwej liczby -1 * plus możliwości przeciążania, nie czyni * (-1) sztuczką.
ThunderGr

93

W ten sam sposób, w jaki robisz wszystko inne jako ujemne: umieść przed nim znak minus.

var positive = 6;
var negative = -positive;

8
Każdy zapomina o jednoargumentowym minusie.
rekurencyjny

Jaka jest praktyczna różnica między tą a tą odpowiedzią: stackoverflow.com/questions/1348080/… int myNegInt = System.Math.Abs(myNumber) * (-1);
goodguys_activate

@ makerofthings7, ten, z którym łączysz się, to o wiele więcej instrukcji procesora - operacja o wartości bezwzględnej (co najmniej trzy instrukcje na x86), po której następuje MUL (lub prawdopodobnie NEG, jeśli kompilator jest sprytny). Ta odpowiedź to pojedynczy, lekki kod operacyjny NEG, nic więcej ani mniej niż to, czego potrzebujesz. Oczywiście obie odpowiedzi zachowują się inaczej, gdy wprowadzona liczba jest już ujemna; Jeśli (w przeciwieństwie do tego pytania) Twój wkład może być negatywny, decyzja należy do Ciebie.
Joe White

41

Uwaga dla wszystkich, którzy odpowiedzieli

- Math.Abs(myInteger)

lub

0 - Math.Abs(myInteger)

lub

Math.Abs(myInteger) * -1

jako sposób na zachowanie ujemnych liczb i zmienianie dodatnich na ujemne.

To podejście ma jedną wadę. Nie działa dla wszystkich liczb całkowitych. Zakres Int32typów wynosi od „-2 31 ” do „2 31 - 1”. Oznacza to, że jest jeszcze jedna liczba „ujemna”. W konsekwencji Math.Abs(int.MinValue)rzuca plik OverflowException.

Prawidłowym sposobem jest użycie instrukcji warunkowych:

int neg = n < 0 ? n : -n;

To podejście działa dla „wszystkich” liczb całkowitych.


Rzucę ci kwestię poprawności, ale każdy kod, który zależy od tego, kto nie bierze Abs MinValue, jest kruchy.
Steven Sudit

Steven: Czasami rozwiązujesz problem (taki jak Abs), na który prawdopodobnie nie można zadziałać int.MinValue(zakładając inttyp zwrotu). W takim przypadku rzucenie wyjątku jest całkowicie OK. Jednak ten konkretny problem ma „prawidłowy” wynik dla, int.MinValueale zgłasza wyjątek, jeśli wybierzesz Abstrasę.
Mehrdad Afshari

Po stwierdzeniu, że skala ujemna jest większa niż dodatnia, idziesz i sugerujesz kod, który tego nie uwzględnia. Jeśli nto -32768wtedy -njest też -32768!!! Co więcej, int neg = n < 0 ? n : -n;prawdopodobnie nie może działać we wszystkich przypadkach, ponieważ jedna z trójskładników absolutnie nic nie robi.
Clive Galway

20

Łatwa droga:

myInt *= -1;

1
Miał zamiar opublikować to samo, każdy powinien pokazać * = trochę miłości :-)
Brian Scott

16
int negInt = 0 - myInt;

Lub gwarantowane, że będzie negatywne.

int negInt = -System.Math.Abs(someInt);

11

Aby zmienić znak liczby całkowitej, wystarczy użyć operatora znaku:

myInt = -myInt;

Aby była ujemna, niezależnie od tego, czy oryginalna wartość jest ujemna, czy nie, najpierw użyj metody Abs:

myInt = -Math.Abs(myInt);

6

Dla większej zabawy:

int myInt = Math.Min(hisInt, -hisInt);

int myInt = -(int)Math.Sqrt(Math.Pow(Math.Sin(1), 2) + Math.Pow(Math.Cos(-1), 2))
            * Math.Abs(hisInt);

2
Zbyt ryzykowne, IMHO. Co jeśli zmieni się definicja koła?
MusiGenesis

6

EDYCJA: To jest złe dla dodatnich wejść ... Popełniłem błąd zapominając, że pozostałe bity w -x (2s-wartość dopełnienia) są „przeciwieństwem” ich wartości w + x, a nie to samo. WIĘC prosta zmiana bitu znaku NIE zadziała dla liczb dodatnich.

Zostawię to tutaj do celów ...

Lub podstępny sposób (myślę) ...

int y = x | ~ int.MaxValue;

cause int.MaxValue is 0111 1111 1111 1111 1111 1111 1111 1111

więc

~int.MaxValue is      1000 0000 0000 0000 0000 0000 0000 0000

i dlatego każdy int32 Or'ed z tym umieści 1 w bicie znaku (czyniąc go ujemnym) i pozostawi wszystkie inne bity takie same ...

EDYCJA: faktycznie, ponieważ 1000 0000 0000 0000 0000 0000 0000 0000 jest w rzeczywistości wartością minimalną, powinno to również działać:

   int y = x | int.MinValue; // or, to do it to itself,
   x |= int.MinValue;

Czyli ujemne zero równa się int.MinValue?
rekurencyjny

Nie, w uzupełnieniu do dwóch nie ma ujemnego zera. wszystkie są ujemne 1. A Signed 8Bit Int: 10000000 to -128
Charles Bretana

1
+1, ponieważ nikt nie zasługuje na to, aby go zlekceważyć za odpowiedź na pytanie typu „jaka litera jest po A, ale przed C?”
MusiGenesis

... i, dzięki poniższej odpowiedzi @ Mehrad, jest to jedyne podejście, które działa, gdy dane wejściowe to int.MinValue ...
Charles Bretana

Charles: To jest złe. W przypadku liczb ujemnych działa, ale w przypadku liczb dodatnich samo odwrócenie znaku nie daje -number. 1to same zera i jedynka. Or int.MinValue-1
-ing

6

Mimo, że na imprezę się tutaj spóźniłem, zamierzam dodać kilka przydatnych sztuczek z czasów, kiedy byłem sprzętem. Wszystkie te zakładają reprezentację komplementu 2 dla liczb ze znakiem.

int negate = ~i+1;
int positiveMagnitude = (i ^ (i>>31)) - (i>>31);
int negativeMagnitude = (i>>31) - (i ^ (i>>31));

Chcesz to bardziej wyjaśnić? z i == int.MinValue, to wszystkie zmienne to-2147483648
Clive Galway,

5

Dla żartu:

int negativeInt = int.Parse(String.Format("{0}{1}", 
    "-", positiveInt.ToString()));

Aktualizacja : piękno tego podejścia polega na tym, że można go łatwo zmienić w generator wyjątków:

int negativeInt = int.Parse(String.Format("{0}{1}", 
    "thisisthedumbestquestioninstackoverflowhistory", positiveInt.ToString()));

5

używam myInt = -myInt;

Tak proste i łatwe

Jeśli chcesz mieć tylko pozytywne

myInt = myInt>0 ? myInt : -myInt;

Szukałem tej odpowiedzi w nieco innej sytuacji niż PO. Chcę, aby 2 wartości były wzajemnie negowane, jeśli jedna z nich wynosi -5, a druga powinna wynosić 5, dlatego jest to moje najlepsze rozwiązanie = D
Mathieu Brouwers

dostaniesz przepełnienie, ponieważ int.MaxValuejest 2147483647, nawet var i = int.MaxValue; i++;nie zadziała
CMS

4
long negativeNumber = (long)positiveInt - (long)(int.MaxValue + 1);

Nikt nie powiedział, że musi to być jakaś konkretna liczba ujemna.


Hm, jeśli nie obchodzi cię, że musi to być konkretna liczba ujemna, możesz uprościć to do "długiej ujemnej liczby = -1;"
Beska

@Guffa: to właściwie żart.
MusiGenesis,




0

Zamiana liczby z dodatniej na ujemną lub z ujemnej na dodatnią:

public static decimal Reverse(this decimal source)
{
     return source * decimal.MinusOne;
}

0

Po prostu coś, czym chcę się podzielić.

public decimal NumberReevaluate(decimal number, bool isPositive)
{
    var tempNumber = System.Math.Abs(number);
    return isPositive ? tempNumber : -tempNumber;
}

1
number >= 0 == isPositive ? number : -number
Vitaliy

0

Jak wspomniano wcześniej, zwykłe pomnożenie przez -1 nie jest fajne, ponieważ int.MinValue * -1 == int.MinValue

To naprawdę zależy od twojej aplikacji, ale dla mojej (odwracanie osi joysticka) chcę mieć pewność, że wszystkie skrajności są nadal osiągalne i zachować jak największą wierność.
W tym celu * -1
mapuję Max <--> Min i wszystko pomiędzy dostaje a Używając tej techniki, -32767 jest nieosiągalne podczas odwracania.

private static int Invert(int value) { if (value == int.MaxValue) return int.MinValue; if (value == int.MinValue) return int.MaxValue; return value * -1; }


Odwrócenie do 5nie jest -5, ale 1/5.
dafie

-2

Użyj binarnego i usuń ostatni bit odpowiedzialny za znak ujemny.

Lub użyj binarnego lub, aby dodać znak do typu danych.

To rozwiązanie może brzmieć absurdalnie i niekompletnie, ale gwarantuję, że to najszybsza metoda.

Jeśli nie eksperymentujesz z tym, co zamieściłem, ten post może wyglądać fatalnie: D

Np. Dla int:

Int jest 32-bitowym typem danych, więc ostatni bit (32-ty) określa znak.

I z wartością, która ma 0 na 32 miejscu, a reszta 1. Przekształci ujemne nie na + ve.

Wręcz przeciwnie lub z wartością 1 na 32 miejscu i resztą 0.


-3

X=*-1może nie działać na wszystkich kompilatorach ... ponieważ czyta „pomnóż” „ODEJMOWANIE” 1 zamiast NEGATYWNY Im lepszy alt jest X=(0-X), [KTÓRY JEST RÓŻNY OD X-=X]

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.