Лучшие практики использования положительных и отрицательных чисел в C #

Есть 2 распространенных способа преобразовать положительное число в отрицательное и наоборот:

var a = -a;

и

var a = (-1)*a;

Насколько я знаю, предпочтительнее второе, но почему? И есть ли другой лучший способ преобразования знака числа (int, float, double и т. Д.)?

РЕДАКТИРОВАТЬ: есть ли разница в унарной минусовой операции и умножении на -1?


person Ivan Yuriev    schedule 24.03.2016    source источник
comment
Что заставляет вас думать, что второе предпочтительнее? Мне это кажется ужасно запутанным. Обратите внимание, что ни один из них не будет работать, как вы наивно ожидали, если a равно int.MinValue / _3 _...   -  person Jon Skeet    schedule 24.03.2016
comment
Я думаю, вы имеете в виду int a = 1 и a = -a что-то в этом роде.   -  person J3soon    schedule 24.03.2016
comment
Я имею в виду любое число ... Итак, Джон Скит - вы правы, но вы не предлагаете правильной версии и не ответили на мой вопрос   -  person Ivan Yuriev    schedule 24.03.2016
comment
Я всегда делал; а = -а; а = Math.Abs ​​(а);   -  person PhillipH    schedule 24.03.2016
comment
Почему у этого вопроса столько минусов - посмотрите этот пост с рейтингом 238+: stackoverflow.com/questions/1348080/   -  person Ivan Yuriev    schedule 24.03.2016


Ответы (2)


На сайте http://tryroslyn.azurewebsites.net/ вы можете увидеть код, сгенерированный компилятором.

И для:

using System;
public class C {
    public int M() {
        int a = -2;

        a = -a;

        return a;               
    }

    public int M1() {
        int a = 3;

        a = (-1) * a;

        return a;
    }
}

Компилятор генерирует:

.class private auto ansi '<Module>'
{
} // end of class <Module>

.class public auto ansi beforefieldinit C
    extends [mscorlib]System.Object
{
    // Methods
    .method public hidebysig 
        instance int32 M () cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 4 (0x4)
        .maxstack 8

        IL_0000: ldc.i4.s -2
        IL_0002: neg
        IL_0003: ret
    } // end of method C::M

    .method public hidebysig 
        instance int32 M1 () cil managed 
    {
        // Method begins at RVA 0x2058
        // Code size 8 (0x8)
        .maxstack 2
        .locals init (
            [0] int32
        )

        IL_0000: ldc.i4.3
        IL_0001: stloc.0
        IL_0002: ldc.i4.m1
        IL_0003: ldloc.0
        IL_0004: mul
        IL_0005: stloc.0
        IL_0006: ldloc.0
        IL_0007: ret
    } // end of method C::M1

    .method public hidebysig specialname rtspecialname 
        instance void .ctor () cil managed 
    {
        // Method begins at RVA 0x206c
        // Code size 7 (0x7)
        .maxstack 8

        IL_0000: ldarg.0
        IL_0001: call instance void [mscorlib]System.Object::.ctor()
        IL_0006: ret
    } // end of method C::.ctor

} // end of class C

Как видите, код для метода M i намного проще и короче. Тогда -a - лучший способ.

person BWA    schedule 24.03.2016
comment
Ох, спасибо! Это то, что я ищу! - person Ivan Yuriev; 24.03.2016

Я не понимаю, почему вы думаете, что второй будет предпочтительнее, поскольку первый намного проще, и я использую этот метод все время. Второй метод также очень распространен, но он не используется, поскольку вы хотели бы написать наименьшее количество кода, но если вы планируете все прояснить ... тогда я бы предпочел второй метод. Вы также можете использовать Math.abs (x), если хотите, но я определенно предпочитаю первый метод. Если вы хотите узнать больше о Math.abs, вы можете найти множество руководств через Google. Надеюсь, это каким-то образом разрешило ваш вопрос. :)

person alexo1001    schedule 24.03.2016