'*********************************************************************** 'Include "_FuncionesEnterosConSigno.bas" ******************************* 'By COS, 02/2023, 10/16, 06/16, 10/14, 09/14, 08/14, 12/13, 08/13 ****** 'Pic18 Basic Compiler v4.37 ******************************************** '*********************************************************************** 'CONSTANTES Y SYMBOLOS: Const _AsByte = 0 'Tipo Byte Const _AsWord = 1 'Tipo Word Const _AsLong = 2 'Tipo Long '*********************************************************************** '*********************************************************************** 'FUNCIONES PARA TRABAJAR CON NÚMEROS CON SIGNO TIPO BYTE Y WORD: '_SigDiv16(), _SigMul16(), _SigSub16(), _SigAdd16(), _SigCmp16(), _SigGet16() '_SigGet8(), _SigCpl16(), _SigCpl8(), _SigMod16(), _SigMod8(), _SigSet16() '_SigSet8(), _SegExt16(), _SegExt8(). 'FUNCIONES PARA TRABAJAR CON NÚMEROS CON SIGNO TIPO BYTE, WORD Y LONG: 'Constantes: _AsByte(), _AsWord(), _AsLong() '_SigDiv(), _SigMul(), _SigSub(), _SigAdd(), _SigCmp(), _SigGet() '_SigCpl(), _SigMod(), _SigSet(), _SegExt(), _SigSingle(). '*********************************************************************** '_SigDiv16(): División con signo 16Bit, entera. 'Call _SigDiv16(Word, Word) '_SigMul16(): Multiplicación con signo 16bit, entera. 'Call _SigMul16(Word, Word) '_SigSub16(): Resta con signo 16Bit, entera (activar la función si se usa). 'Call _SigDiv16(Word, Word) '_SigAdd16(): Suma con signo 16Bit, entera. 'Call _SigAdd16(Word, Word) '_SigCmp16(): Compara dos números con signo de 16bit. 'Call _SigCmp16(Word, Word) '_SigGet16(): devuelve el signo variables 16bit, 1 = -, 0 = +. 'Call _SigGet16(Word) '_SigGet8(): Devuelve el signo variables 8bit, 1 = -, 0 = +. 'Call _SigGet8(Byte) '_SigCpl16(): Invierte el signo de una variable 16Bit. 'Call _SigCpl16(Word) '_SigCpl8(): Invierte el signo de una variable 8Bit. 'Call _SigCpl8(Byte) '_SigMod16(): Devuelve el modulo de una variable con signo 16Bit. 'Call _SigMod16(Word) '_SigMod8(): Devuelve el modulo de una variable con signo 8Bit. 'Call _SigMod8(Byte) '_SigSet16(): Asigna signo a las variables 16Bit. 'Call _SigSet16("-", Word) '_SigSet8(): Asigna signo a las variables 8Bit. 'Call _SigSet8("-", Byte) '_SigExt16(): Extender signo tipo 8bit a tipo 16bit. 'Call _SigExt16(Byte) '_SigExt8(): Extender signo tipo 16bit a tipo 8bit. 'Call _SigExt8(Word) '*************************************************************************** 'Tipos de variables (hay que especificar los tipos de variables de entrada): 'Const _AsByte = 0 'Tipo Byte 'Const _AsWord = 1 'Tipo Word 'Const _AsLong = 2 'Tipo Long '_SigDiv(): División con signo hasta 32Bit, entera. 'Call _SigDiv(Byte, _AsByte, Long, _AsLong) '_SigMul(): Multiplicación con signo hasta 32bit, entera. 'Call _SigMul(Byte, _AsByte, Long, _AsLong) '_SigSub(): Resta con signo hasta 32Bit, entera (activar la función si se usa). 'Call _SigSub(Byte, _AsByte, Long, _AsLong) '_SigAdd(): Suma con signo hasta 32Bit, entera. 'Call _SigAdd(Byte, _AsByte, Long, _AsLong) '_SigCmp(): Compara dos números con signo hasta 32bit. 'Call _SigCmp(Byte, _AsByte, Long, _AsLong) '_SigGet(): devuelve el signo variables hasta 32bit, 1 = -, 0 = +. 'Call _SigGet(Byte, _AsByte) '_SigCpl(): Invierte el signo de una variable hasta 32Bit. 'Call _SigCpl(Byte, _AsByte) '_SigMod(): Devuelve el modulo de una variable con signo hasta 32Bit. 'Call _SigMod(Byte, _AsByte) '_SigSet(): Asigna signo a las variables hasta 32Bit. 'Call _SigSiv("-", Byte, _AsByte) '_SigExt(): Extender signo tipo Byte, Word y Long. 'Call _SigExt(Byte, _AsByte, Long, _AsLong) 'Byte to Long. '_SigSingle(): Cambia de tipos Byte, Word o Long a tipo Single. 'Call _SigSingle(_Byte, AsByte) '**************************************************************************** '_SigToString(): Retorna una cadena con signo 'Call _SigToString(_sig32 As Long, _tipo As Byte) '**************************************************************************** '**************************************************************************** 'FUNCIONES PARA TRABAJAR CON NÚMEROS CON SIGNO TIPO BYTE Y WORD: *** '**************************************************************************** 'Retorna valor: Word 'División con signo 16Bit, entera. Function _SigDiv16(_op2 As Word, _op1 As Word) As Word Dim _sigop1 As Bit Dim _sigop2 As Bit Dim _sigaux As Word _sigop1 = _op1.15 'Guarda signo _sigop2 = _op2.15 'Guarda signo _op2.15 = 0 'Elimina el signo _op1.15 = 0 'Elimina el signo If _op1 > 0 Then _sigaux = _op2 / _op1 If _sigop2 = 1 And _sigop1 = 0 Then If _sigaux > 0 Then Toggle _sigaux.15 'Invierte el signo Endif If _sigop2 = 0 And _sigop1 = 1 Then If _sigaux > 0 Then Toggle _sigaux.15 'Invierte el signo Endif Endif If _op1 = 0 Then _sigaux = 32768 'E = -0 "ERROR" _SigDiv16 = _sigaux End Function 'Retorna: valor tipo Long con signo. 'División con signo hasta 32Bit, entera. Function _SigDiv(_op2 As Long, _tipo2 As Byte, _op1 As Long, _tipo1 As Byte) As Long Dim _sigop1 As Bit Dim _sigop2 As Bit If _tipo1 = 0 Then _sigop1 = _op1.7 'Guarda signo If _tipo1 = 1 Then _sigop1 = _op1.15 'Guarda signo If _tipo1 = 2 Then _sigop1 = _op1.31 'Guarda signo If _tipo2 = 0 Then _sigop2 = _op2.7 'Guarda signo If _tipo2 = 1 Then _sigop2 = _op2.15 'Guarda signo If _tipo2 = 2 Then _sigop2 = _op2.31 'Guarda signo If _tipo1 = 0 Then _op1.7 = 0 'Elimina signo If _tipo1 = 1 Then _op1.15 = 0 'Elimina signo If _tipo1 = 2 Then _op1.31 = 0 'Elimina signo If _tipo2 = 0 Then _op2.7 = 0 'Elimina signo If _tipo2 = 1 Then _op2.15 = 0 'Elimina signo If _tipo2 = 2 Then _op2.31 = 0 'Elimina signo If _op1 > 0 Then _SigDiv = _op2 / _op1 If _sigop2 = 1 And _sigop1 = 0 Then If _SigDiv > 0 Then Toggle _SigDiv.31 'Invierte el signo Endif If _sigop2 = 0 And _sigop1 = 1 Then If _SigDiv > 0 Then Toggle _SigDiv.31 'Invierte el signo Endif Endif If _op1 = 0 Then _SigDiv = 2147483648 'E = -0 "ERROR" End Function 'Retorna valor: Word 'Multiplicación con signo 16Bit, entera. Function _SigMul16(_op2 As Word, _op1 As Word) As Word Dim _sigop1 As Bit Dim _sigop2 As Bit Dim _sigaux As Word _SigMul16 = 0 _sigop1 = _op1.15 'Guarda signo _sigop2 = _op2.15 'Guarda signo _op2.15 = 0 'Elimina el signo _op1.15 = 0 'Elimina el signo If _op2 = 0 Or _op1 = 0 Then Exit _sigaux = _op2 * _op1 If _sigop2 = 1 And _sigop1 = 0 Then If _sigaux > 0 Then Toggle _sigaux.15 'Invierte el signo Endif If _sigop2 = 0 And _sigop1 = 1 Then If _sigaux > 0 Then Toggle _sigaux.15 'Invierte el signo Endif _SigMul16 = _sigaux End Function 'Retorna: valor tipo Long con signo 'Multiplicación con signo hasta 32Bit, entera. Function _SigMul(_op2 As Long, _tipo2 As Byte, _op1 As Long, _tipo1 As Byte) As Long Dim _sigop1 As Bit Dim _sigop2 As Bit _SigMul = 0 If _tipo1 = 0 Then _sigop1 = _op1.7 'Guarda signo If _tipo1 = 1 Then _sigop1 = _op1.15 'Guarda signo If _tipo1 = 2 Then _sigop1 = _op1.31 'Guarda signo If _tipo2 = 0 Then _sigop2 = _op2.7 'Guarda signo If _tipo2 = 1 Then _sigop2 = _op2.15 'Guarda signo If _tipo2 = 2 Then _sigop2 = _op2.31 'Guarda signo If _tipo1 = 0 Then _op1.7 = 0 'Elimina signo If _tipo1 = 1 Then _op1.15 = 0 'Elimina signo If _tipo1 = 2 Then _op1.31 = 0 'Elimina signo If _tipo2 = 0 Then _op2.7 = 0 'Elimina signo If _tipo2 = 1 Then _op2.15 = 0 'Elimina signo If _tipo2 = 2 Then _op2.31 = 0 'Elimina signo If _op2 = 0 Or _op1 = 0 Then Exit _SigMul = _op2 * _op1 If _sigop2 = 1 And _sigop1 = 0 Then If _SigMul > 0 Then Toggle _SigMul.31 'Invierte el signo Endif If _sigop2 = 0 And _sigop1 = 1 Then If _SigMul > 0 Then Toggle _SigMul.31 'Invierte el signo Endif End Function 'Retorna valor: Word 'Resta con signo 16Bit, entera. 'Activar si se va a utilizar ****************************************** Function _sigsub16(_op2 As Word, _op1 As Word) As Word If _op1 > 0 Then Toggle _op1.15 'Invierte el signo _sigsub16 = _SigAdd16(_op2, _op1) End Function '------------------------------------------------------------------------ 'Retorna: variable tipo Long con signo. 'Resta con signo hasta 32Bit, entera. 'Activar las lineas si se va a utilizar ********************************** Function _sigsub(_op2 As Long, _tipo2 As Byte, _op1 As Long, _tipo1 As Byte) As Long If _op1 > 0 Then If _tipo1 = 0 Then Toggle _op1.7 'Invierte signo If _tipo1 = 1 Then Toggle _op1.15 'Invierte signo If _tipo1 = 2 Then Toggle _op1.31 'Invierte signo Endif _sigsub = _SigAdd(_op2, _tipo2, _op1, _tipo1) 'Activar la linea si se va a utilizar End Function '------------------------------------------------------------------------- 'Retorna valor: Word 'Suma con signo 16Bit, entera. Function _SigAdd16(_op2 As Word, _op1 As Word) As Word Dim _sigop1 As Bit Dim _sigop2 As Bit _sigop1 = _op1.15 'Guarda signo _sigop2 = _op2.15 'Guarda signo _op2.15 = 0 'Elimina el signo _op1.15 = 0 'Elimina el signo If _sigop2 = 0 And _sigop1 = 0 Then _SigAdd16 = _op1 + _op2 If _sigop2 = 1 And _sigop1 = 0 Then If _op2 > _op1 Then _SigAdd16 = _op2 - _op1 If _SigAdd16 > 0 Then Toggle _SigAdd16.15 'Invierte signo Endif If _op2 < _op1 Then _SigAdd16 = _op1 - _op2 If _op2 = _op1 Then _SigAdd16 = 0 Endif If _sigop2 = 0 And _sigop1 = 1 Then If _op2 > _op1 Then _SigAdd16 = _op2 - _op1 Endif If _op2 < _op1 Then _SigAdd16 = _op1 - _op2 If _SigAdd16 > 0 Then Toggle _SigAdd16.15 'Invierte signo Endif If _op2 = _op1 Then _SigAdd16 = 0 Endif If _sigop2 = 1 And _sigop1 = 1 Then _SigAdd16 = _op2 + _op1 Toggle _SigAdd16.15 'Invierte signo Endif End Function 'Retorna: valor tipo Long con signo 'Suma con signo hasta 32Bit, entera. Function _SigAdd(_op2 As Long, _tipo2 As Byte, _op1 As Long, _tipo1 As Byte) As Long Dim _sigop1 As Bit Dim _sigop2 As Bit If _tipo1 = 0 Then _sigop1 = _op1.7 'Guarda signo If _tipo1 = 1 Then _sigop1 = _op1.15 'Guarda signo If _tipo1 = 2 Then _sigop1 = _op1.31 'Guarda signo If _tipo2 = 0 Then _sigop2 = _op2.7 'Guarda signo If _tipo2 = 1 Then _sigop2 = _op2.15 'Guarda signo If _tipo2 = 2 Then _sigop2 = _op2.31 'Guarda signo If _tipo1 = 0 Then _op1.7 = 0 'Elimina signo If _tipo1 = 1 Then _op1.15 = 0 'Elimina signo If _tipo1 = 2 Then _op1.31 = 0 'Elimina signo If _tipo2 = 0 Then _op2.7 = 0 'Elimina signo If _tipo2 = 1 Then _op2.15 = 0 'Elimina signo If _tipo2 = 2 Then _op2.31 = 0 'Elimina signo If _sigop2 = 0 And _sigop1 = 0 Then _SigAdd = _op1 + _op2 If _sigop2 = 1 And _sigop1 = 0 Then If _op2 > _op1 Then _SigAdd = _op2 - _op1 If _SigAdd > 0 Then Toggle _SigAdd.31 'Invierte signo Endif If _op2 < _op1 Then _SigAdd = _op1 - _op2 If _op2 = _op1 Then _SigAdd = 0 Endif If _sigop2 = 0 And _sigop1 = 1 Then If _op2 > _op1 Then _SigAdd = _op2 - _op1 Endif If _op2 < _op1 Then _SigAdd = _op1 - _op2 If _SigAdd > 0 Then Toggle _SigAdd.31 'Invierte signo Endif If _op2 = _op1 Then _SigAdd = 0 Endif If _sigop2 = 1 And _sigop1 = 1 Then _SigAdd = _op2 + _op1 Toggle _SigAdd.31 'Invierte signo Endif End Function 'Retorna valor: Byte 'Compara dos números con signo de 16bit 'Devuelve en _sigcmp16: '0 = _op2 < _op1 '1 = _op2 > _op1 '2 = _op2 = _op1 Function _SigCmp16(_op2 As Word, _op1 As Word) As Byte Dim _sigop2 As Bit Dim _sigop1 As Bit _sigop1 = _op1.15 'Guarda signo _sigop2 = _op2.15 'Guarda signo _op2.15 = 0 'Elimina el signo _op1.15 = 0 'Elimina el signo If _sigop2 = 0 And _sigop1 = 0 Then If _op2 < _op1 Then _SigCmp16 = 0 If _op2 > _op1 Then _SigCmp16 = 1 If _op2 = _op1 Then _SigCmp16 = 2 Endif If _sigop2 = 0 And _sigop1 = 1 Then _SigCmp16 = 1 Endif If _sigop2 = 1 And _sigop1 = 0 Then _SigCmp16 = 0 Endif If _sigop2 = 1 And _sigop1 = 1 Then If _op2 > _op1 Then _SigCmp16 = 0 If _op2 < _op1 Then _SigCmp16 = 1 If _op2 = _op1 Then _SigCmp16 = 2 Endif End Function 'Retorna valor: Byte 'Compara dos números con signo hasta 32bit 'Devuelve en _sigcmp: '0 = _op2 < _op1 '1 = _op2 > _op1 '2 = _op2 = _op1 Function _SigCmp(_op2 As Long, _tipo2 As Byte, _op1 As Long, _tipo1 As Byte) As Byte Dim _sigop2 As Bit Dim _sigop1 As Bit If _tipo1 = 0 Then _sigop1 = _op1.7 'Guarda signo If _tipo1 = 1 Then _sigop1 = _op1.15 'Guarda signo If _tipo1 = 2 Then _sigop1 = _op1.31 'Guarda signo If _tipo2 = 0 Then _sigop2 = _op2.7 'Guarda signo If _tipo2 = 1 Then _sigop2 = _op2.15 'Guarda signo If _tipo2 = 2 Then _sigop2 = _op2.31 'Guarda signo If _tipo1 = 0 Then _op1.7 = 0 'Elimina signo If _tipo1 = 1 Then _op1.15 = 0 'Elimina signo If _tipo1 = 2 Then _op1.31 = 0 'Elimina signo If _tipo2 = 0 Then _op2.7 = 0 'Elimina signo If _tipo2 = 1 Then _op2.15 = 0 'Elimina signo If _tipo2 = 2 Then _op2.31 = 0 'Elimina signo If _sigop2 = 0 And _sigop1 = 0 Then If _op2 < _op1 Then _SigCmp = 0 If _op2 > _op1 Then _SigCmp = 1 If _op2 = _op1 Then _SigCmp = 2 Endif If _sigop2 = 0 And _sigop1 = 1 Then _SigCmp = 1 Endif If _sigop2 = 1 And _sigop1 = 0 Then _SigCmp = 0 Endif If _sigop2 = 1 And _sigop1 = 1 Then If _op2 > _op1 Then _SigCmp = 0 If _op2 < _op1 Then _SigCmp = 1 If _op2 = _op1 Then _SigCmp = 2 Endif End Function 'Retorna valor: Bit 'Devuelve el signo variables 16bit, 1 = -, 0 = + Function _SigGet16(_op As Word) As Bit _SigGet16 = _op.15 End Function 'Retorna valor: Bit 'Devuelve el signo variables 8bit, 1 = -, 0 = + Function _SigGet8(_op As Byte) As Bit _SigGet8 = _op.7 End Function 'Retorna valor: Bit 'Devuelve el signo variable Byte, Word o Long, 1 = -, 0 = + Function _SigGet(_op As Long, _tipo As Byte) As Bit If _tipo = 0 Then _SigGet = _op.7 If _tipo = 1 Then _SigGet = _op.15 If _tipo = 2 Then _SigGet = _op.31 End Function 'Retorna valor: Word 'Invierte el signo de una variable 16Bit Function _SigCpl16(_op As Word) As Word Toggle _op.15 _SigCpl16 = _op End Function 'Retorna valor: Byte 'Invierte el signo de una variable 8Bit Function _SigCpl8(_op As Byte) As Byte Toggle _op.7 _SigCpl8 = _op End Function 'Retorna valor: Long 'Invierte el signo a una variable Byte, Word o Long Function _SigCpl(_op As Long, _tipo As Byte) As Long If _tipo = 0 Then Toggle _op.7 If _tipo = 1 Then Toggle _op.15 If _tipo = 2 Then Toggle _op.31 _SigCpl = _op End Function 'Devuelve el modulo de una variable con signo 16Bit Function _SigMod16(_op As Word) As Word _op.15 = 0 _SigMod16 = _op End Function 'Retorna valor: Byte 'Devuelve el modulo de una variable con signo 8Bit Function _SigMod8(_op As Byte) As Byte _op.7 = 0 _SigMod8 = _op End Function 'Retorna valor: Long 'Devuelve el modulo de una variable Byte, Word o Long Function _SigMod(_op As Long, _tipo As Byte) As Long If _tipo = 0 Then _op.7 = 0 If _tipo = 1 Then _op.15 = 0 If _tipo = 2 Then _op.31 = 0 _SigMod = _op End Function 'Retorna valor: Word 'Asigna signo a las variables 16Bit Function _SigSet16(_sig As Byte, _op As Word) As Word If _op > 0 And _sig = "-" Then _op.15 = 1 Else _op.15 = 0 Endif _SigSet16 = _op End Function 'Retorna valor: Byte 'Asigna signo a las variables 8Bit Function _SigSet8(_sig As Byte, _op As Byte) As Byte If _op > 0 And _sig = "-" Then _op.7 = 1 Else _op.7 = 0 Endif _SigSet8 = _op End Function 'Retorna valor: Long 'Asigna signo a la variable Byte, Word o Long Function _sigSet(_sig As Byte, _op As Long, _tipo As Byte) As Long If _op > 0 And _sig = "-" Then If _tipo = 0 Then _op.7 = 1 If _tipo = 1 Then _op.15 = 1 If _tipo = 2 Then _op.31 = 1 Else If _tipo = 0 Then _op.7 = 0 If _tipo = 1 Then _op.15 = 0 If _tipo = 2 Then _op.31 = 0 Endif _sigSet = _op End Function 'Extender signo tipo 16bit a tipo 8bit Function _SigExt8(_op As Word) As Byte _SigExt8 = _op.LB _SigExt8.7 = _op.15 End Function 'Retorna valor: Word 'Extender signo tipo 8bit a tipo 16bit Function _SigExt16(_op As Byte) As Word _SigExt16 = _op _SigExt16.15 = _op.7 _SigExt16.7 = 0 End Function 'Retorna valor: Long 'Extiende el signo a una variable Byte, Word o Long Function _SigExt(_op As Long, _tipo As Byte, _tipo1 As Byte) As Long _SigExt = 0 'De Byte a Word If _tipo = 0 And _tipo1 = 1 Then _op.15 = _op.7 _op.7 = 0 Endif 'De Byte a Long If _tipo = 0 And _tipo1 = 2 Then _op.31 = _op.7 _op.7 = 0 Endif 'De Word a Long If _tipo = 1 And _tipo1 = 2 Then _op.31 = _op.15 _op.15 = 0 Endif 'De Word a Byte If _tipo = 1 And _tipo1 = 0 Then _op.7 = _op.15 _op.HB = 0 Endif 'De Long a Byte If _tipo = 2 And _tipo1 = 0 Then _op.7 = _op.31 _op.4B = 0 _op.3B = 0 _op.HB = 0 Endif 'De Long a word If _tipo = 2 And _tipo1 = 1 Then _op.15 = _op.31 _op.4B = 0 _op.3B = 0 Endif _SigExt = _op End Function 'Retorna valor: Single 'Pasa de entero con signo Byte, Word o Long a tipo Single Function _SigSingle(_dato As Long, _tipo As Byte) As Single Dim _signo As Bit If _tipo = 0 Then _signo = _dato.7 _dato.7 = 0 Endif If _tipo = 1 Then _signo = _dato.15 _dato.15 = 0 Endif If _tipo = 2 Then _signo = _dato.31 _dato.31 = 0 Endif If _signo = 1 Then _SigSingle = _dato * -1 If _signo = 0 Then _SigSingle = _dato End Function 'Retorna cadena 'Retorna una cadena con formato signo 'Hay que especificar el tipo de dato Function _SigToString(_sig32 As Long, _tipo As Byte) As String 'Variables 8Bit Dim _bit As Bit If _tipo = 0 Then _bit = _sig32.7 _sig32.7 = 0 Endif 'Variables 16Bit If _tipo = 1 Then _bit = _sig32.15 _sig32.15 = 0 Endif 'variables 32bit If _tipo = 2 Then _bit = _sig32.31 _sig32.31 = 0 Endif 'Hace la conversión y pone el signo If _bit = 1 Then _SigToString = "-" + #_sig32 If _bit = 0 Then _SigToString = #_sig32 End Function