Página 1 de 1

Conversão de fragmento de código xBase para C usando a API

Enviado: 08 Ago 2013 16:32
por NaldoDj
Pessoal,

Boa tarde.

Estou me familiarizando com ambiente Harbour e, para isso, estou fazendo um programa para calcular números muito grandes, ao estilo BIGNUM do Java. É um programa didático que me permite explorar as características e o poder da linguagem. Acontece que alguns fragmentos do código teriam um melhor desempenho se fossem escritos diretamente em C e estou tendo uma certa dificuldade por não conhecer a fundo a API do Harbour. Será que poderia me ajudar? O Código fonte está no GitHub: github.com/NaldoDj/tBigNumber e as funções que quero converter para C são as: ADD, Sub e Mult.

Código: Selecionar todos

	#IFDEF TBN_ARRAY

	/*
		Funca        : Add
		Autor         : Marinaldo de Jesus [http://www.blacktdn.com.br]
		Data          : 04/02/2013
		Descricao   : Adicao
		Sintaxe      : Add(a,b,n,nBase) -> cNR
	*/
	Static Function Add(a,b,n,nBase)

		Local y	:= n+1
		Local c := aFill(aSize(__aZAdd,y),0)
		Local k := 1

		While n>0
		#IFDEF __PROTHEUS__
			c[k] += Val(SubStr(a,n,1))+Val(SubStr(b,n,1))
		#ELSE
			c[k] += Val(a[n])+Val(b[n])
		#ENDIF
			IF c[k]>=nBase
				c[k+1]	+= 1
				c[k]	-= nBase
			EndIF
			++k
			--n
		End While

	Return(aGetcN(c,y))
	
	/*
		Funcao		: Sub
		Autor       : Marinaldo de Jesus [http://www.blacktdn.com.br]
		Data        : 04/02/2013
		Descricao   : Subtracao
		Sintaxe     : Sub(a,b,n,nBase) -> cNR
	*/
	Static Function Sub(a,b,n,nBase)

		Local y := n
		Local c := aFill(aSize(__aZSub,y),0)
		Local k := 1
	
		While n>0
		#IFDEF __PROTHEUS__
			c[k] += Val(SubStr(a,n,1))-Val(SubStr(b,n,1))
		#ELSE
			c[k] += Val(a[n])-Val(b[n])
		#ENDIF
			IF c[k]<0
				c[k+1]	-= 1
				c[k]	+= nBase
			EndIF
			++k
			--n
		End While

	Return(aGetcN(c,y))
	
	/*
		Funcao		: Mult
		Autor       : Marinaldo de Jesus [http://www.blacktdn.com.br]
		Data        : 04/02/2013
		Descricao   : Multiplicacao de Inteiros
		Sintaxe     : Mult(cN1,cN2,n,nBase) -> cNR
		Obs.		: Mais rapida,usa a multiplicacao nativa
	*/
	Static Function Mult(cN1,cN2,n,nBase)

		Local a	:= tBigNInvert(cN1,n)
		Local b	:= tBigNInvert(cN2,n)

		Local y	:= n+n
		Local c	:= aFill(aSize(__aZMult,y),0)
	
		Local i := 1
		Local k := 1
		Local l := 2
		
		Local s
		Local x
		Local j
	
		While i<=n
			s := 1
			j := i
			While s<=i
			#IFDEF __PROTHEUS__
				c[k] += Val(SubStr(a,s++,1))*Val(SubStr(b,j--,1))
			#ELSE
				c[k] += Val(a[s++])*Val(b[j--])
			#ENDIF
			End While
			IF c[k]>=nBase
				x		:= k+1
				c[x]	:= Int(c[k]/nBase)
				c[k]	-= c[x]*nBase
			EndIF
			k++
			i++
		End While
	
		While l<=n
			s := n
			j := l
			While s>=l
			#IFDEF __PROTHEUS__
				c[k] += Val(SubSTr(a,s--,1))*Val(SubSTr(b,j++,1))
			#ELSE
				c[k] += Val(a[s--])*Val(b[j++])	
			#ENDIF
			End While
			IF c[k]>=nBase
				x		:= k+1
				c[x]	:= Int(c[k]/nBase)
				c[k]	-= c[x]*nBase
			EndIF
			k++
			IF k>=y
				EXIT
			EndIF
			l++
		End While

	Return(aGetcN(c,k))

	/*
		Funcao		: aGetcN
		Autor       : Marinaldo de Jesus [http://www.blacktdn.com.br]
		Data        : 04/02/2013
		Descricao   : Montar a String de Retorno
		Sintaxe     : aGetcN(a,x) -> s
	*/
	Static Function aGetcN(a,n)
	
		Local s	:= ""
		Local y	:= n
	
		While y>=1
			While y>=1 .and. a[y]==0
				y--
			End While
			While y>=1
				s	+= hb_ntos(a[y])
				y--
			End While
		End While
	
		IF s==""
			s := "0"
		EndIF
	
		IF Len(s)<n
			s := PadL(s,n,"0")
		EndIF
	
	Return(s)
	
	#ELSE

	/*
		Funcao		: Add
		Autor       : Marinaldo de Jesus [http://www.blacktdn.com.br]
		Data        : 04/02/2013
		Descricao   : Adicao
		Sintaxe     : Add(a,b,n,nBase) -> cNR
	*/
	Static Function Add(a,b,n,nBase)

		Local c

		Local y	:= n+1
		Local k := 1
	
		Local v := 0
		Local v1
		
		While y>__nstcZ0
			__cstcZ0+=SubStr(__cstcZ0,1,__nstcZ0)
			__nstcZ0+=__nstcZ0
		End While
		
		c := SubStr(__cstcZ0,1,y)

		While n>0
			#IFDEF __PROTHEUS__
				v += Val(SubStr(a,n,1))+Val(SubStr(b,n,1))
			#ELSE
				v += Val(a[n])+Val(b[n])
			#ENDIF
			IF v>=nBase
				v  -= nBase
				v1 := 1
			Else
				v1 := 0
			EndIF
			#IFDEF __PROTHEUS__
				c := Stuff(c,k,1,hb_ntos(v))
				c := Stuff(c,k+1,1,hb_ntos(v1)) 
			#ELSE
				c[k]   := hb_ntos(v)
				c[k+1] := hb_ntos(v1)
			#ENDIF
			v := v1
			++k
			--n
		End While

	Return(cGetcN(c,y))
	
	/*
		Funcao		: Sub
		Autor       : Marinaldo de Jesus [http://www.blacktdn.com.br]
		Data        : 04/02/2013
		Descricao   : Subtracao
		Sintaxe     : Sub(a,b,n,nBase) -> cNR
	*/
	Static Function Sub(a,b,n,nBase)

		Local c

		Local y := n
		Local k := 1
		
		Local v := 0
		Local v1
		
		While y>__nstcZ0
			__cstcZ0+=SubStr(__cstcZ0,1,__nstcZ0)
			__nstcZ0+=__nstcZ0
		End While
		
		c := SubStr(__cstcZ0,1,y)
	
		While n>0
			#IFDEF __PROTHEUS__
				v += Val(SubStr(a,n,1))-Val(SubStr(b,n,1))
			#ELSE
				v += Val(a[n])-Val(b[n])
			#ENDIF
			IF v<0
				v  += nBase
				v1 := -1
			Else
				v1 := 0
			EndIF
			#IFDEF __PROTHEUS__
				c := Stuff(c,k,1,hb_ntos(v)) 
			#ELSE
				c[k] := hb_ntos(v)
			#ENDIF
			v := v1
			++k
			--n
		End While

	Return(cGetcN(c,y))
	
	/*
		Funcao		: Mult
		Autor       : Marinaldo de Jesus [http://www.blacktdn.com.br]
		Data        : 04/02/2013
		Descricao   : Multiplicacao de Inteiros
		Sintaxe     : Mult(cN1,cN2,n,nBase) -> cNR
		Obs.		: Mais rapida, usa a multiplicacao nativa
	*/
	Static Function Mult(cN1,cN2,n,nBase)

		Local c

		Local a	:= tBigNInvert(cN1,n)
		Local b	:= tBigNInvert(cN2,n)

		Local y	:= n+n

		Local i := 1
		Local k := 1
		Local l := 2
		
		Local s
		Local j
		
		Local v	:= 0
		Local v1
		
		While y>__nstcZ0
			__cstcZ0+=SubStr(__cstcZ0,1,__nstcZ0)
			__nstcZ0+=__nstcZ0
		End While
		
		c	:= SubStr(__cstcZ0,1,y)
			
		While i<=n
			s := 1
			j := i
			While s<=i
			#IFDEF __PROTHEUS__
				v += Val(SubStr(a,s++,1))*Val(SubStr(b,j--,1))
			#ELSE
				v += Val(a[s++])*Val(b[j--])
			#ENDIF
			End While
			IF v>=nBase
				v1	:= Int(v/nBase)
				v	-= v1*nBase
			Else
				v1	:= 0	
			EndIF
			#IFDEF __PROTHEUS__
				c := Stuff(c,k,1,hb_ntos(v))
				c := Stuff(c,k+1,1,hb_ntos(v1)) 
			#ELSE
				c[k]   := hb_ntos(v)
				c[k+1] := hb_ntos(v1)
			#ENDIF
			v := v1
			k++
			i++
		End While
		
		#IFDEF __PROTHEUS__
			v := Val(SubStr(c,k,1))
		#ELSE
			v := Val(c[k])
		#ENDIF	
	
		While l<=n
			s := n
			j := l
			While s>=l
			#IFDEF __PROTHEUS__
				v += Val(SubSTr(a,s--,1))*Val(SubSTr(b,j++,1))
			#ELSE
				v += Val(a[s--])*Val(b[j++])	
			#ENDIF
			End While
			IF v>=nBase
				v1	:= Int(v/nBase)
				v	-= v1*nBase
			Else
				v1	:= 0	
			EndIF
			#IFDEF __PROTHEUS__
				c := Stuff(c,k,1,hb_ntos(v))
				c := Stuff(c,k+1,1,hb_ntos(v1)) 
			#ELSE
				c[k]   := hb_ntos(v)
				c[k+1] := hb_ntos(v1)
			#ENDIF
			v := v1
			k++
			IF k>=y
				EXIT
			EndIF
			l++
		End While

	Return(cGetcN(c,k))

	/*
		Funcao		: cGetcN
		Autor       : Marinaldo de Jesus [http://www.blacktdn.com.br]
		Data        : 04/02/2013
		Descricao   : Montar a String de Retorno
		Sintaxe     : cGetcN(c,n) -> s
	*/
	Static Function cGetcN(c,n)
	
		Local s	:= ""
		Local y	:= n
	
		While y>=1
		#IFDEF __PROTHEUS__
			While y>=1 .and. SubStr(c,y,1)=="0"
		#ELSE
			While y>=1 .and. c[y]=="0"
		#ENDIF	
				y--
			End While
			While y>=1
			#IFDEF __PROTHEUS__
				s += SubStr(c,y,1)
			#ELSE
				s += c[y]
			#ENDIF
				y--
			End While
		End While
	
		IF s==""
			s := "0"
		EndIF
	
		IF Len(s)<n
			s := PadL(s,n,"0")
		EndIF
	
	Return(s)
	
	#ENDIF
Alguém poderia me auxiliar?

[]s
Naldo

Conversão de fragmento de código xBase para C usando a API

Enviado: 08 Ago 2013 16:56
por NaldoDj

Conversão de fragmento de código xBase para C usando a API

Enviado: 08 Ago 2013 17:19
por NaldoDj
Um pequeno fragmento do que estou querendo fazer é esse:

Código: Selecionar todos

/*
	Funcao		: tBigNInvert
	Autor       : Marinaldo de Jesus [http://www.blacktdn.com.br]
	Data        : 04/02/2013
	Descricao   : Inverte o Numero
	Sintaxe     : tBigNInvert(c,n) -> s
*/
#IFDEF __PROTHEUS__
	Static Function tBigNInvert(c,n)
		Local s := ""
		Local y	:= n
		While y>0
		#IFDEF __PROTHEUS__
			s += SubStr(c,y--,1)
		#ELSE
			s += c[y--]
		#ENDIF
		End While
	Return(s)
#ELSE
	Static Function tBigNInvert(c,n)
		SYMBOL_UNUSED(n)
	Return(__tBigNInvert(c))
	#pragma BEGINDUMP
		#include "hbapi.h"
		#include "hbapiitm.h"
		//Ref.: Descend.c => Harbour Descend() function
		HB_FUNC( __TBIGNINVERT ){
			PHB_ITEM pItem = hb_param( 1, HB_IT_STRING );
			HB_SIZE nLen = hb_itemGetCLen( pItem );
			char * szBuffer = ( char * ) hb_xgrab( nLen + 1 );
			hb_strDescend( szBuffer, hb_itemGetCPtr( pItem ), nLen );
			hb_retclen_buffer( szBuffer, nLen );
		}
	#pragma ENDDUMP
#ENDIF
Onde substituo o código xBase por chamada a funções da API diretamente em C para tornar a execução do código mais rápida.

Conversão de fragmento de código xBase para C usando a API

Enviado: 08 Ago 2013 23:58
por NaldoDj
Corrigindo o código em C para a inversão da String

Código: Selecionar todos

	#pragma BEGINDUMP
		#include "hbapi.h"
		#include "hbapiitm.h"
		HB_FUNC( TBIGNINVERT ){
			PHB_ITEM pItem = hb_param(1,HB_IT_STRING);
			HB_SIZE s = (HB_SIZE)hb_parnint(2);
			HB_SIZE f = s;
			HB_SIZE t = 0;
			char * szStringTo = ( char * ) hb_xgrab(s+1);
			const char * szStringFrom = hb_itemGetCPtr(pItem);
			for(;f;){
				szStringTo[t++]=szStringFrom[--f];
			}
			hb_retclen_buffer(szStringTo,s);
		}
	#pragma ENDDUMP

Conversão de fragmento de código xBase para C usando a API

Enviado: 09 Ago 2013 15:57
por NaldoDj
A função, ADD, utilizando String, ficou assim:

Código: Selecionar todos

		Static Function Add(a,b,n,nBase)
			Local c := tBigNAdd(a,b,n,nBase)
		Return(cGetcN(c,n+1))
		#pragma BEGINDUMP
			#include "hbapi.h"
			#include "hbapiitm.h"
			HB_FUNC( TBIGNADD ){	
				const char * a  = hb_itemGetCPtr(hb_param(1,HB_IT_STRING));
				const char * b  = hb_itemGetCPtr(hb_param(2,HB_IT_STRING));
				HB_SIZE n  = (HB_SIZE)hb_parnint(3);
				HB_ISIZ nB = hb_parns(4);
				HB_SIZE y  = n+1;
				char * c = ( char * ) hb_xgrab(y+1);
				HB_SIZE k = 0;
				int v = 0;
				int v1;
				a += n-1;
				b += n-1;
				while (n){
					v += hb_strVal((char*)a--,1)+hb_strVal((char*)b--,1);
					if ( v>=nB ){
						v  -= nB;
						v1 = 1;
					}	
					else{
						v1 = 0;
					}
					c[k]   = "0123456789ABCEFGHIJKLMNOPQRSTUV"[v%nB];
					c[k+1] = "0123456789ABCEFGHIJKLMNOPQRSTUV"[v1%nB];
					v = v1;
					++k;
					--n;
				}
				hb_retclen_buffer(c,y);
			}
		#pragma ENDDUMP

Estou testando-a, aparentemente os valores estão OK. Mas não sei se poderia otimizar +.

[]s
Naldo

Conversão de fragmento de código xBase para C usando a API

Enviado: 15 Ago 2013 22:24
por Vlademiro
Diz Marinaldo,

Bem que eu gostaria de poder lhe ajudar, mas não conheço BEM a forma como o harbour interage com a linguagem C. Dei uma olhada no seu código mas não entendi muito não. :%

Estou estudando pelo tutorial :
http://www.elektrosoft.it/tutorials/har ... #clanguage

Mas esse tutorial é bem básico. Ele me ajuda mas não se aprofunda muito.
Também vi como o velho Clipper interage, mas mudou muita coisa.

Você teria alguma documentação que respondesse a algumas dúvidas básicas :

(1) Como recebo uma string, processo a mesma e retorno uma string ?

Ex : Uma função que receba uma string e retorne o inverso da mesma

(2) Como recebo um array de qualquer valor e retorno um valor qualquer ?

Ex : Uma função que calcula a média de N elementos que são passados como arrays.

Estou estudando a linguagem C atualmente e seria de grande ajuda . Desculpe se acabei respondendo a pergunda com outra, mas o assunto não é muito debatido e vi que seria uma boa oportunidade para mim.

Conversão de fragmento de código xBase para C usando a API

Enviado: 18 Ago 2013 20:24
por yugi386
Prezado NaldoDj,

De fato a implementação de números grandes em harbour deve ser feita com funções strings e o desempenho é sempre prejudicado. Creio que você deve estar estudando crioptografia (RSA por exemplo) que trata de números gigantes para criar as chaves públicas e privadas.

Um linguagem em que esta implementação é mais fácil é em Ruby ou em Python porque tem nativamente o suporte para números grandes. O problema é que estas linguagens são interpretadas e não geram um arquivo executável.

Eu implementei o RSA em Ruby e, mesmo a linguagem tendo suporte a números grandes ainda foi preciso utilizar alguns artificios para gerar chaves de 8192 bits, por exemplo. Você pode ver o código completo desta implementação em:

https://gist.github.com/yugi386/1525523

As funções implementadas neste link são:

1. CALCULA O MÁXIMO DIVISOR COMUM ENTRE DOIS NÚMEROS
2. CALCULA O MÍNIMO MULTIPLO COMUM DE DOIS NUMEROS
3. FUNÇÃO PARA EXPONENCIAÇÃO RÁPIDA
4. ALGORITMO DE RABIN MILLER, VERIFICA SE UM NÚMERO PODE SER PRIMO
5. CALCULA O INVERSO MULTIPLICATIVO DE UM NÚMERO EM UMA BASE
6. GERA TABELA DE PRIMOS ATÉ 1.000.000
7. GERA UM NÚMERO ALEATÓRIO ATÉ DADO LIMITE
8. FUNÇÃO PARA A GERAÇÃO DE UM CHAVE RSA COM 1024, 2048, 4096 e 8192 BITS.

A sintaxe do Ruby é muito semelhante à sintaxe do clipper/Harbour. Ironicamente Ruby (uma linguagem moderna) imita o clipper!!! Por isto que gosto do Harbour!!!!

Quanto à interação de Harbour com C você pode se guiar pelos seguintes passos:

1. Você precisa criar uma interface Harbour para chamar a função C.
2. Escreva a função C.
3. Atenha-se aos parâmetros e retornos de funções para poder recuperar os valores em Harbour. Existem funções especificas para passar e receber parametros de uma função em C.

Veja um exemplo prático:

Código: Selecionar todos

// --------------------------------------------------------------------------------------
// MOSTRANDO A INTERATIVIDADE ENTRE HARBOUR E C
// --------------------------------------------------------------------------------------
Function Main
   private palavra := ""

   ? "============================"
   ? "Integrando Harbour com C"
   ? "============================"
   ? ""

   // Agora queremos que a variável palavra seja modificada pela função retorno
   // que está escrita em C

   Palavra := time()
   ? "String Inicial.: " + palavra
   Palavra := retorno(palavra)
   ? "String Final...: " + palavra

   inkey(0)
Return
// --------------------------------------------------------------------------------------

// Atenção: Código C
#pragma BEGINDUMP  // Inicio do codigo C

   // Passo 1 -> Aqui você deve declarar #define e #include para 
   //            que sua função C funcione. Faça como se estivesse programando em C 
   
   #include <stdio.h>
   #include <string.h>
   #include "hbapi.h"

   // Passo 2 -> aqui você faz a declaração das funções no C
      char* retorno(char* palavra);  // FUNÇÃO EM C QUE Recebe e RETORNA UMA STRING

   // Passo 3 -> aqui você faz uma interface em Harbour para acessar a função em C:
   
HB_FUNC ( RETORNO )  // aqui sempre em maiúsculo com o nome da função sem parametros e parenteses
{
   hb_retc( retorno((char*)hb_parc(1)) );  // recebe e retorna string
}   

   /* LEIA ABAIXO COM ATENÇÃO A EXPLICAÇÃO DA FUNÇÃO DE INTERFACE!!!!
   
   Obs: hb_parc(1) diz que o primeiro parametro da função é uma string 
      se existirem mais parametros você deve usar hb_parc(2), hb_parc(3), etc...
      isto se os parametros forem strings. Caso forem outros consulte a tabela
      de parametros e retornos do harbour (logo abaixo)   
      --------------------------------------------
      observe o cast (char*) que informa a função C que o parametro é string
      a função hb_retc pega a string retornada pela função C e devolve para o Harbour
      se o parametro for de outro tipo o cast será outro: exemplo (int) ou (float)

   ==========================================================   
      COM ESTAS FUNÇÕES NÓS PEGAMOS O RETORNO DA FUNÇÃO EM C
   ==========================================================
      hb_ret() Post a NIL return value
      hb_reta() Returns an array with a specific length
      hb_retc() Returns a string
      hb_retclen() Returns a string with a specific length
      hb_retd() Returns a date
      hb_retdl() Returns a long value as a julian date
      hb_retds() Returns a date, must use yyyymmdd format
      hb_retl() Returns a logical integer
      hb_retnd() Returns a double
      hb_retndlen() Returns a double, with specific width and decimals
      hb_retni() Returns a integer number
      hb_retnilen() Returns a integer number, with specific width
      hb_retnl() Returns a long number
      hb_retnlen() Returns a double, with specific width and decimals
      hb_retnllen() Returns a long number, with specific width 
   
   =====================================================================
   COM ESTAS FUNÇÕES NÓS PASSAMOS PARÂMETROS DO HARBOUR PARA A FUNÇÃO C
   =====================================================================
      hb_param() Retrieve a direct pointer to an item parameter
      hb_parc() Retrieve a string parameter
      hb_parclen() Retrieve a string parameter length
      hb_parcsiz() Retrieve a by-reference string parameter length, including terminator
      hb_pards() Retrieve a date as a string yyyymmdd
      hb_pardsbuff() Retrieve a date as a string yyyymmdd
      hb_parinfa() Retrieve length or element type of an array parameter
      hb_parinfo() Determine the param count or data type
      hb_parl() Retrieve a logical parameter as an int
      hb_parnd() Retrieve a numeric parameter as a double
      hb_parni() Retrieve a numeric parameter as a integer
      hb_parnl() Retrieve a numeric parameter as a long 
*/   

// Passo 4 -> A função em C propriamente dita:

char* retorno(char* palavra)   // RETORNA UMA STRING
{
   
   char teste[] = " - retorno em C";
   char dss[25];
   
   strcat(dss, palavra);   // concatena strings
   strcat(dss, teste);   // concatena strings

   return dss;  // string de retorno...
}

#pragma ENDDUMP   // fim do código em C
   
Espero ter ajudado!!

abraço,

Yugi.

OBS: se quiser dê uma olhada no SHJ, um algoritmo criptografico que criei e escrevi em C: http://wverissimo.webnode.com/news/um-a ... trico-shj/

Conversão de fragmento de código xBase para C usando a API

Enviado: 20 Fev 2014 17:44
por NaldoDj
Consegui evoluir com tBigNumber e converter as funções de adição, subtração multiplicação e divisão para C tornando o processo mais rápido. Mas percebi que em 64 o sistema se comporta de maneira inesperada e retorna, por vezes, valores errados no que diz respeito à divisão. Será que alguém pode me dar uma luz? O fragmento do código é esse:

Código: Selecionar todos

		typedef struct
		{
			char * cDivQ;
			char * cDivR;
		} stBIGNeDiv, * ptBIGNeDiv;

        static void __TBIGNeDIV(const char * cN, const char * cD, HB_SIZE n, const HB_ISIZ nB , HB_SIZE y, ptBIGNeDiv peDiv){

			PHB_ITEM peDVArr = hb_itemArrayNew(0);

			char * szPADL    = __TBIGNPADL("1",n,"0");

			char * cDivDvD   = (char*)hb_xgrab(y);
			memcpy(cDivDvD,szPADL,n);

			hb_xfree(szPADL);

			char * cDivDvR   = (char*)hb_xgrab(y);
			memcpy(cDivDvR,cD,n);

			szPADL		     = __TBIGNPADL("0",n,"0");

			peDiv->cDivQ	 = (char*)hb_xgrab(y);
			memcpy(peDiv->cDivQ,szPADL,n);

			hb_xfree(szPADL);

			peDiv->cDivR     = (char*)hb_xgrab(y);
			memcpy(peDiv->cDivR,peDiv->cDivQ,n);

			HB_MAXUINT nI    = 0;

			char * tmp;

			while (strcmp(cDivDvR,cN)<=0){

				++nI;

     			PHB_ITEM pNI = hb_itemArrayNew(2);

		        hb_arraySetC(pNI,1,cDivDvD);
		        hb_arraySetC(pNI,2,cDivDvR);
	 			hb_arrayAddForward(peDVArr,pNI);  

	 			hb_itemRelease(pNI);
    			
    			tmp = __TBIGNADD(cDivDvD,cDivDvD,n,n,nB);
    			memcpy(cDivDvD,tmp,n);
    			hb_xfree(tmp);

				tmp = __TBIGNADD(cDivDvR,cDivDvR,n,n,nB);				
				memcpy(cDivDvR,tmp,n);
				hb_xfree(tmp);

			}

			while (nI){

				PHB_ITEM pNI = hb_arrayGetItemPtr(peDVArr,nI);

				tmp = __TBIGNADD(peDiv->cDivR,hb_arrayGetCPtr(pNI,2),n,n,nB);
				memcpy(peDiv->cDivR,tmp,n);
				hb_xfree(tmp);

				tmp = __TBIGNADD(peDiv->cDivQ,hb_arrayGetCPtr(pNI,1),n,n,nB);
				memcpy(peDiv->cDivQ,tmp,n);
				hb_xfree(tmp);
                
				int iCmp = strcmp(peDiv->cDivR,cN);

				if (iCmp==0){
					break;
				} else{
						if (iCmp==1){
							tmp = __TBIGNSUB(peDiv->cDivR,hb_arrayGetCPtr(pNI,2),n,n,nB);
							memcpy(peDiv->cDivR,tmp,n);
							hb_xfree(tmp);
							tmp = __TBIGNSUB(peDiv->cDivQ,hb_arrayGetCPtr(pNI,1),n,n,nB);
							memcpy(peDiv->cDivQ,tmp,n);
							hb_xfree(tmp);
					}
				}  

				--nI;

			}

			hb_itemRelease(peDVArr);

			hb_xfree(cDivDvD);
			hb_xfree(cDivDvR);

			tmp = __TBIGNSUB(cN,peDiv->cDivR,n,n,nB);
			memcpy(peDiv->cDivR,tmp,n);
			hb_xfree(tmp);

		}

		HB_FUNC( TBIGNEDIV ){

			const char * cN  = hb_parc(1);
			const char * cD  = hb_parc(2);
			HB_SIZE n        = (HB_SIZE)hb_parnint(4);
			HB_SIZE y        = n+1;
			const HB_ISIZ nB = (HB_MAXUINT)hb_parnint(5);

			ptBIGNeDiv peDiv = (ptBIGNeDiv)hb_xgrab(sizeof(stBIGNeDiv));

			__TBIGNeDIV(cN,cD,n,nB,y,peDiv);

			hb_storclen(peDiv->cDivR,n,3);
			hb_retclen(peDiv->cDivQ,n);

			hb_xfree(peDiv->cDivR);
			hb_xfree(peDiv->cDivQ);
			hb_xfree(peDiv);
		}
O link para a versão atual é:https://github.com/NaldoDj/tBigNumber/b ... number.prg

e o do projeto como um todo: https://github.com/NaldoDj/tBigNumber/

Se alguém tiver um tempo para me auxiliar ficarei grato.

[]s
Naldo DJ.

Conversão de fragmento de código xBase para C usando a API

Enviado: 24 Fev 2014 11:47
por NaldoDj
Fiz algumas alterações no código e consegui resolver o problema. Agora funciona igual tanto em 32 quanto em 64. O novo código ficou assim:

Código: Selecionar todos

		typedef struct
		{
			char * cDivQ;
			char * cDivR;
		} stBIGNeDiv, * ptBIGNeDiv;

        static void __TBIGNeDIV(const char * cN, const char * cD, HB_SIZE n, const HB_MAXUINT nB , ptBIGNeDiv peDiv){
	
			PHB_ITEM peDVArr    = hb_itemArrayNew(0);
		
			ptBIGNeDiv peDivTmp = (ptBIGNeDiv)hb_xgrab(sizeof(stBIGNeDiv));
			
			char * szPADL       = __TBIGNPADL("1",n,"0");
			peDivTmp->cDivQ     = hb_strdup(szPADL);
			hb_xfree(szPADL);
			
			peDivTmp->cDivR     = hb_strdup(cD);
	
			szPADL		        = __TBIGNPADL("0",n,"0");
			peDiv->cDivQ	    = hb_strdup(szPADL);
			peDiv->cDivR        = hb_strdup(szPADL);
			hb_xfree(szPADL);
			
			HB_MAXUINT nI       = 0;

			while (strcmp(peDivTmp->cDivR,cN)<=0){

     			PHB_ITEM pNI = hb_itemArrayNew(2);
		        
			        hb_arraySetC(pNI,1,peDivTmp->cDivQ);
			        hb_arraySetC(pNI,2,peDivTmp->cDivR);
		 			hb_arrayAddForward(peDVArr,pNI);  

					char * tmp = __TBIGNADD(peDivTmp->cDivQ,peDivTmp->cDivQ,n,n,nB);
	    			memcpy(peDivTmp->cDivQ,tmp,n);
	    			hb_xfree(tmp);
					
					tmp        = __TBIGNADD(peDivTmp->cDivR,peDivTmp->cDivR,n,n,nB);				
					memcpy(peDivTmp->cDivR,tmp,n);
					hb_xfree(tmp);

	 			hb_itemRelease(pNI);

				++nI;

			}
			
			hb_xfree(peDivTmp->cDivQ);
			hb_xfree(peDivTmp->cDivR);

			while (nI){

				PHB_ITEM pNI = hb_arrayGetItemPtr(peDVArr,nI);
				
				peDivTmp->cDivQ = __TBIGNADD(peDiv->cDivQ,hb_arrayGetCPtr(pNI,1),n,n,nB);
				memcpy(peDiv->cDivQ,peDivTmp->cDivQ,n);
				hb_xfree(peDivTmp->cDivQ);
    
    			peDivTmp->cDivR = __TBIGNADD(peDiv->cDivR,hb_arrayGetCPtr(pNI,2),n,n,nB);
				memcpy(peDiv->cDivR,peDivTmp->cDivR,n);
				hb_xfree(peDivTmp->cDivR);
	            
				int iCmp = strcmp(peDiv->cDivR,cN);

				if (iCmp==0){
					break;
				} else{
						if (iCmp==1){
	
							peDivTmp->cDivQ = __TBIGNSUB(peDiv->cDivQ,hb_arrayGetCPtr(pNI,1),n,n,nB);
							memcpy(peDiv->cDivQ,peDivTmp->cDivQ,n);
							hb_xfree(peDivTmp->cDivQ);
	
							peDivTmp->cDivR = __TBIGNSUB(peDiv->cDivR,hb_arrayGetCPtr(pNI,2),n,n,nB);
							memcpy(peDiv->cDivR,peDivTmp->cDivR,n);
							hb_xfree(peDivTmp->cDivR);
	
					}
				}  
				
				--nI;
				
			}

			hb_itemRelease(peDVArr);
	
			peDivTmp->cDivR = __TBIGNSUB(cN,peDiv->cDivR,n,n,nB);
			memcpy(peDiv->cDivR,peDivTmp->cDivR,n);
			hb_xfree(peDivTmp->cDivR);
			hb_xfree(peDivTmp);
				
		}
		
		HB_FUNC( TBIGNEDIV ){
			
			const char * cN     = hb_parc(1);
			const char * cD     = hb_parc(2);
			HB_SIZE n           = (HB_SIZE)hb_parnint(4);
			const HB_MAXUINT nB = (HB_MAXUINT)hb_parnint(5);
			
			ptBIGNeDiv peDiv = (ptBIGNeDiv)hb_xgrab(sizeof(stBIGNeDiv));
			
			__TBIGNeDIV(cN,cD,n,nB,peDiv);
			
			hb_storclen(peDiv->cDivR,n,3);
			hb_retclen(peDiv->cDivQ,n);

			hb_xfree(peDiv->cDivR);
			hb_xfree(peDiv->cDivQ);
			hb_xfree(peDiv);
		}



[]s
Naldo