double int no Harbour?

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

ArnaldoND
Usuário Nível 1
Usuário Nível 1
Mensagens: 23
Registrado em: 23 Jan 2019 16:12
Localização: são paulo/sp

double int no Harbour?

Mensagem por ArnaldoND »

como inicializar uma variavel double int no harbour?

preciso de uma variavel numerica muito grande, pois fiz uma função que faz a consistencia do digito de verificação do numero do processo do TJSP, cujo calculo se baseia em:

1111111-DD-2222-3-44-555555

onde:
DD = 98 - MOD ( 11111112222344555555 , 97 )
ou
DD = 98 - ( 11111112222344555555 % 97 )

Quando 1111111 está "cheio", a função está calculando errado! acredito q se deva ao tamanho do numero , que é inteiro.. porque? se eu calculo o seguinte numero de processo: 0004939-48-2013-8-26-029900, o resultado é OK (retorna-me 48), porém, se eu tento 1044645-26-2019-8-26-010000, retorna um numero nada a ver, provavelmente devido à truncamento durante a manipulação da variavel
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

double int no Harbour?

Mensagem por JoséQuintas »

Talvez dividir no meio e fazer em duas etapas.
A precisão numérica é de 16 caracteres, e aí tem mais que isso.
Supondo que sejam 22 dígitos, dois blocos de 11.
Como na primeira operação vai sobrar no máximo 96, concatenado ao segundo vão ser apenas 13.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

double int no Harbour?

Mensagem por JoséQuintas »

Direto no fórum, não testei....

Código: Selecionar todos

cNumeroGrande := Padl( cOriginal, 24 )

cParte1 := Substr( cNumeroGrande, 1, 12 )
nResto := Mod( Val( cParte1 ), 97 )

cParte2 := StrZero( nResto, 2 ) + Substr( cNumeroGrande, 13 )
nResto := Mod( Val( cParte2 ), 97 )
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

double int no Harbour?

Mensagem por asimoes »

Tenho esse fonte veja se te ajuda:

Incluir no hpb

Funções:

C_SUM -> Soma
C_SUB ->Subtração
C_MULT -) Multiplicação
C_DIV - Divisão
Anexos
C_OPER.C
Operações
(4.35 KiB) Baixado 178 vezes
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
ArnaldoND
Usuário Nível 1
Usuário Nível 1
Mensagens: 23
Registrado em: 23 Jan 2019 16:12
Localização: são paulo/sp

double int no Harbour?

Mensagem por ArnaldoND »

JoseQuintas, tua solução foi perfeita... a matemática é fascinante kkk
obrigado
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

double int no Harbour?

Mensagem por JoséQuintas »

É parecido com o que a gente faz "a caneta", exceto que não olhamos pelos zeros

85 / 3

8 / 3 = 2 sobra 2
junta o 2 no 5 que tinha sobrado temos 25
25 / 3 = 8 sobra 1

Nessa divisão em duas partes... é como se fosse 80 / 30, que sobra 20, trabalhando tudo na mesma grandeza, dezena.
"2" + "5", por causa da posição do número, o 2 acaba representando os 20, sem precisar fazer outra conta.
Digamos que é usar truques, pra facilitar contas.

Basicamente o mesmo jeito de fazer "a caneta", mas ajustado para quantidade de casas que o Harbour "aguenta", pra não precisar muita conta.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

double int no Harbour?

Mensagem por asimoes »

Não sei qual é o resultado esperado na sua rotina

? C_RESTO( NN, DD)

Código: Selecionar todos

#pragma BEGINDUMP

#include <windows.h>
#include <windef.h>
#include <tlhelp32.h>
#include <hbapi.h>
#include <hbapiitm.h>

HB_FUNC ( C_RESTO )
{
        
  ULONGLONG para1;
  ULONGLONG para2;
  ULONGLONG resulta;
        
  para1 = hb_parnint(1);
  para2 = hb_parnint(2);

  resulta = (para1 % para2);

  hb_retnll(resulta);

}
#pragma ENDDUMP
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

double int no Harbour?

Mensagem por JoséQuintas »

asimoes escreveu:Não sei qual é o resultado esperado na sua rotina
Inverto a pergunta:
Como vai passar os números com mais de 16 dígitos, se o limite do Harbour é 16 dígitos?

? c_Resto( 55555555555555555555, 33333333333333333333)
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

double int no Harbour?

Mensagem por JoséQuintas »

Xi..... Fiz uns testes...

Código: Selecionar todos

PROCEDURE Main

   LOCAL a, b

   a := 555555555555555555555
   b := 333333333333333333333
   ? c_Resto( a, b )
   Inkey(0)

   RETURN
Retornou zero
Acho que acabou com limite baixo.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

double int no Harbour?

Mensagem por JoséQuintas »

O difícil agora é conferir kkkk

Código: Selecionar todos


PROCEDURE Main

   LOCAL a, b

   a := 555555555555555555555
   b := 97
   ? c_Resto( a, b )
   ? Resto( "555555555555555555555", 97 )
   Inkey(0)

   RETURN

#pragma BEGINDUMP

#include <windows.h>
#include <windef.h>
#include <tlhelp32.h>
#include <hbapi.h>
#include <hbapiitm.h>

HB_FUNC ( C_RESTO )
{

  ULONGLONG para1;
  ULONGLONG para2;
  ULONGLONG resulta;

  para1 = hb_parnint(1);
  para2 = hb_parnint(2);

  resulta = (para1 % para2);

  hb_retnll(resulta);

}
#pragma ENDDUMP

FUNCTION Resto( cOriginal, nDivide )

   LOCAL cNumeroGrande, cParte1, cParte2, nResto

cNumeroGrande := Padl( cOriginal, 24 )

cParte1 := Substr( cNumeroGrande, 1, 12 )
nResto := Mod( Val( cParte1 ), nDivide )

cParte2 := StrZero( nResto, 2 ) + Substr( cNumeroGrande, 13 )
nResto := Mod( Val( cParte2 ), nDivide )

RETURN nResto
Um retorna 79 e outro 17
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

double int no Harbour?

Mensagem por JoséQuintas »

Solução pro teste mais fácil:

Código: Selecionar todos


PROCEDURE Main

   LOCAL a, b

   a := 333333333333333333333
   b := 3
   ? c_Resto( a, b )
   ? Resto( "333333333333333333333", b )
   Inkey(0)

   RETURN
Em C sobra 2, o que é errado, porque o número é divisível por 3....
Realmente o limite não é suficiente para o cálculo que precisa.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

double int no Harbour?

Mensagem por JoséQuintas »

Correção:
os parâmetros numéricos acabam recebendo o número de precisão limitada do Harbour.
Precisa de cuidado sobre aonde ela pode ajudar.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

double int no Harbour?

Mensagem por asimoes »

Quintas,

Pode testar por aqui:
https://www.4devs.com.br/resto_da_divisao
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

double int no Harbour?

Mensagem por asimoes »

Em C pode-se usar fmod ou %

Código: Selecionar todos

#pragma BEGINDUMP

#include <windows.h>
#include <windef.h>
#include <tlhelp32.h>
#include <hbapi.h>
#include <hbapiitm.h>

HB_FUNC ( C_RESTO )
{
        
  ULONGLONG para1;
  ULONGLONG para2;
  double resulta;
        
  para1 = hb_parnint(1);
  para2 = hb_parnint(2);

  //resulta = (para1 % para2); // ou usando fmod 
  
  resulta = fmod( para1, para2 );
  
  hb_retnd(resulta); // retorna double
  
  //hb_retni(resulta); //retorna integer

}
#pragma ENDDUMP
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

double int no Harbour?

Mensagem por asimoes »

Função Mod do harbour

Código: Selecionar todos

/*
 * Mod() function
 *
 * Copyright 1999 Matthew Hamilton <mhamilton@bunge.com.au>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file LICENSE.txt.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA (or visit https://www.gnu.org/licenses/).
 *
 * As a special exception, the Harbour Project gives permission for
 * additional uses of the text contained in its release of Harbour.
 *
 * The exception is that, if you link the Harbour libraries with other
 * files to produce an executable, this does not by itself cause the
 * resulting executable to be covered by the GNU General Public License.
 * Your use of that executable is in no way restricted on account of
 * linking the Harbour library code into it.
 *
 * This exception does not however invalidate any other reasons why
 * the executable file might be covered by the GNU General Public License.
 *
 * This exception applies only to the code released by the Harbour
 * Project under the name Harbour.  If you copy code from other
 * Harbour Project or Free Software Foundation releases into a copy of
 * Harbour, as the General Public License permits, the exception does
 * not apply to the code that you add in this way.  To avoid misleading
 * anyone as to the status of such modified files, you must delete
 * this exception notice from them.
 *
 * If you write modifications of your own for Harbour, it is your choice
 * whether to permit this exception to apply to your modifications.
 * If you do not wish that, delete this exception notice.
 *
 */

#include "hbapi.h"
#include "hbapiitm.h"
#include "hbapierr.h"
#include "hbmath.h"

/* NOTE: In CA-Cl*pper this is written in Clipper, see the source below,
         and the error handling is NOT made here, but in the % operator.
         [vszakats] */

/* NOTE: CA-Cl*pper is buggy since it relies on the fact that the errorhandler
         will silently handle zero division errors. [vszakats] */

/* NOTE: This C version fully emulates the behaviour of the original
         CA-Cl*pper version, including bugs/side-effects. [vszakats] */

HB_FUNC( MOD )
{
   PHB_ITEM pNumber = hb_param( 1, HB_IT_NUMERIC );
   PHB_ITEM pBase   = hb_param( 2, HB_IT_NUMERIC );

   if( pNumber && pBase )
   {
      double dNumber = hb_itemGetND( pNumber );
      double dBase   = hb_itemGetND( pBase ); /* dBase! Cool! */

      if( dBase )
      {
         double dResult = fmod( dNumber, dBase );

         if( dResult && ( dNumber > 0 ? dBase < 0 : dBase > 0 ) )
            dResult += dBase;
         hb_retnd( dResult );
      }
      else
      {
         PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ZERODIV, 1341, NULL, "%", HB_ERR_ARGS_BASEPARAMS );

         /* In CA-Cl*pper Mod() function ignores substitution result
          * and return original numeric item keeping its internal
          * representation: integer or double, size and number of
          * decimal places, it can be seen in code like:
          *    PROCEDURE Main()
          *       Set( _SET_FIXED, .T. )
          *       ? Transform( Mod( 12345, 0 ), "" )
          *       RETURN
          *
          * [druzus]
          */
         if( pResult )
         {
            hb_itemReturn( pNumber );
            hb_itemRelease( pResult );
         }
      }
   }
   else
      hb_errRT_BASE_SubstR( EG_ARG, 1085, NULL, "%", 2, hb_param( 1, HB_IT_ANY ), hb_param( 2, HB_IT_ANY ) );
}

/*
   FUNCTION Mod( cl_num, cl_base )

      LOCAL cl_result := cl_num % cl_base

      RETURN iif( cl_base = 0, cl_num, iif( cl_result * cl_base < 0, cl_result + cl_base, cl_result ) )
 */
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Responder