Wenn man rein auf den erzeugten ASM-Output schaut, dann ist es mit einem "If" am schnellsten. Ich habe noch eine ASM-Lösung dazu gepackt, die genauso lang ist wie die PB-Version mit dem If, da man die Sprungmarke nicht mitzählen darf.
Code: Alles auswählen
Macro BM1(var) ;Bits Minus 1
(SizeOf(var) * 8 - 1)
EndMacro
intValue.i = -1
#VERSION = 5
CompilerSelect #VERSION
CompilerCase 1
intValue = intValue ! (intValue >> BM1(intValue)) + ((intValue >> BM1(intValue)) & 1)
; MOV r15,qword [v_intValue]
; MOV r14,qword [v_intValue]
; SAR r14,63
; XOr r15,r14
; MOV r14,qword [v_intValue]
; SAR r14,63
; And r14,1
; ADD r15,r14
; MOV qword [v_intValue],r15
CompilerCase 2
intValue = intValue * -((((intValue >> BM1(intValue)) & 1) << 1) - 1)
; MOV r15,qword [v_intValue]
; MOV r14,qword [v_intValue]
; SAR r14,63
; And r14,1
; SAL r14,1
; DEC r14
; NEG r14
; IMUL r15,r14
; MOV qword [v_intValue],r15
CompilerCase 3
intValue = intValue * (((intValue >> BM1(intValue)) & 1) * -2 + 1)
; MOV r15,qword [v_intValue]
; MOV r14,qword [v_intValue]
; SAR r14,63
; And r14,1
; IMUL r14,-2
; INC r14
; IMUL r15,r14
; MOV qword [v_intValue],r15
CompilerCase 4
If (intValue < 0)
intValue = -intValue
EndIf
; MOV r15,qword [v_intValue]
; And r15,r15
; JGE _EndIf2
; MOV r15,qword [v_intValue]
; NEG r15
; MOV qword [v_intValue],r15
; _EndIf2:
CompilerCase 5
; CompilerIf Not #PB_Compiler_InlineAssembly
; CompilerError "Bitte zuerst InlineASM in den Compiler-Optionen aktivieren."
; CompilerEndIf
CompilerIf SizeOf(intValue) <> 8
CompilerError "Der ASM-Code funktioniert nur auf einem 64-Bit-System mit einer 64-Bit-Ganzzahlvariablen."
CompilerEndIf
!MOV r15, qword [v_intValue]
!MOV r14, r15
!SAR r14, 63
!XOR r15, r14
!SUB r15, r14
!MOV qword [v_intValue], r15
CompilerEndSelect
Debug intValue