Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fastest way to negate a number

I was thinking this morning here, what would be the fastest way to reverse a number of positive to negative and from negative to positive, of course, the simplest way might be:

int a = 10; a = a*(-1); 

or

int a = 10; a = -a; 

But then, I thought, I take that to do this, using commands shift and pointers ... That really would be possible to change the sign of a value, using commands shift operators and memory?

like image 565
Alexandre Avatar asked Feb 27 '13 11:02

Alexandre


People also ask

How do you negate a number?

Negative numbers can be thought of as resulting from the subtraction of a larger number from a smaller. For example, negative three is the result of subtracting three from zero: 0 − 3 = −3.

How do you take the negation of a number in C++?

function transform(a_begin, a_end, a1_begin, negate()): a_begin = lower bound of the array. a_end = upper bound of the array. a1_end = Lower bound of the second modified array. negate() = to negate the values of the array.


2 Answers

Use something that is readable, such as

a *= -1; 

or

a = -a; 

Leave the rest to the optimizer.

like image 200
Armen Tsirunyan Avatar answered Oct 11 '22 12:10

Armen Tsirunyan


With optimization disabled, gcc for x86 compiles the first to this asm:

    .file   "optimum.c"     .def    ___main;    .scl    2;  .type   32; .endef     .text .globl _main     .def    _main;  .scl    2;  .type   32; .endef _main:     pushl   %ebp     movl    %esp, %ebp     andl    $-16, %esp     subl    $16, %esp     call    ___main               # MinGW library init function     movl    $10, 12(%esp) ;i = 10     negl    12(%esp)      ;i = -i     movl    $0, %eax     leave     ret 

With optimization disabled, the second one produces:

    .file   "optimum.c"     .def    ___main;    .scl    2;  .type   32; .endef     .text .globl _main     .def    _main;  .scl    2;  .type   32; .endef _main:     pushl   %ebp     movl    %esp, %ebp     andl    $-16, %esp     subl    $16, %esp     call    ___main     movl    $10, 12(%esp)   ;i = 10     negl    12(%esp)        ;i = -i     movl    $0, %eax     leave     ret 

Same output! No difference in the assembly code produced.

--------------------------EDIT, OP ANSWERS HE USES VC++2012, INTEL ARCH-------------------

Compiled using cl optimum.c /Fa optimum.asm (optimization disabled)

; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01       TITLE   C:\Users\Dell\Downloads\TTH\TTH\TTH\optimum.c     .686P     .XMM     include listing.inc     .model  flat  INCLUDELIB LIBCMT INCLUDELIB OLDNAMES  PUBLIC  _main ; Function compile flags: /Odtp _TEXT   SEGMENT _a$ = -4                        ; size = 4 _argc$ = 8                      ; size = 4 _argv$ = 12                     ; size = 4 _main   PROC ; File c:\users\dell\downloads\tth\tth\tth\optimum.c ; Line 4     push    ebp     mov ebp, esp     push    ecx ; Line 5     mov DWORD PTR _a$[ebp], 10          ; 0000000aH ; Line 6     mov eax, DWORD PTR _a$[ebp]     neg eax ;1 machine cycle!     mov DWORD PTR _a$[ebp], eax ; Line 7     xor eax, eax ; Line 8     mov esp, ebp     pop ebp     ret 0 _main   ENDP _TEXT   ENDS END 

and with second approach (a = a * -1), optimization disabled MSVC:

; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01       TITLE   C:\Users\Dell\Downloads\TTH\TTH\TTH\optimum.c     .686P     .XMM     include listing.inc     .model  flat  INCLUDELIB LIBCMT INCLUDELIB OLDNAMES  PUBLIC  _main ; Function compile flags: /Odtp _TEXT   SEGMENT _a$ = -4                        ; size = 4 _argc$ = 8                      ; size = 4 _argv$ = 12                     ; size = 4 _main   PROC ; File c:\users\dell\downloads\tth\tth\tth\optimum.c ; Line 4     push    ebp     mov ebp, esp     push    ecx ; Line 5     mov DWORD PTR _a$[ebp], 10          ; 0000000aH ; Line 6     mov eax, DWORD PTR _a$[ebp]     imul    eax, -1 ;1 instruction, 3 machine/cycles :|     mov DWORD PTR _a$[ebp], eax ; Line 7     xor eax, eax ; Line 8     mov esp, ebp     pop ebp     ret 0 _main   ENDP _TEXT   ENDS END 

So if you care about the performance of your debug-mode asm under MSVC, you could optimize your source accordingly. Normally you only care about performance in optimized builds.

like image 40
Aniket Inge Avatar answered Oct 11 '22 11:10

Aniket Inge