Page 3 of 4

Posted: Sat Apr 18, 2009 10:58 pm
by Arctic Fox
netmaestro wrote:Do the library docs say that you need to free the memory?
They don't say that directly (but don't say that MAPM will free it either). Well, perhaps it isn't necessary - it seems to free all the used memory resources automatically. Maybe jack knows more about it.


By the way
jack wrote:Arctic Fox, you must include the import section, if your code is to use the mapm functions, it tell PB and Polink what functions to link into your program.
I meant that I used m_apm_free_all_mem() in the code after ImportC. When compiling it says POLINK: error: Unresolved external symbol '_ftime'. It's the same situation when using m_apm_trim_mem_usage() :(
Do you know why?

Posted: Sat Apr 18, 2009 11:55 pm
by jack
Arctic Fox, I don't know where I got the notion of freeing the memory by the function m_apm_to_fixpt_stringexp but it looks I was wrong, will check on my days off to make sure.
I'll check about the Polink error.

Posted: Sun Apr 19, 2009 12:09 am
by Arctic Fox
Thanks jack :D
Until then I'll stick to the other methods with a buffer string.

Posted: Fri May 01, 2009 10:34 pm
by jack
was trying to resolve the undefined symbol '_ftime" but the only way I found was to build a dll.
to build the dll you need to edit MKALLMGW.BAT
add gcc -shared -o mapm.dll map*.o right after the line ar rc libmapm.a map*.o
then make an import lib by
polib mapm.dll /machine:ix86 /out:libmapm.lib
and copy the dll and importlib to the appropiate places.

but there's a problem, the following line works

Code: Select all

m_apm_to_string(s, 100, PeekL(*pMM_PI))
but this don't work, why?

Code: Select all

*MM_PI             = PeekL(*pMM_PI)
m_apm_to_string(s, 100, *MM_PI)

Code: Select all

Structure  mapm;M_APM_struct
	*m_apm_data.c
	m_apm_id.l
	m_apm_refcount.l;int
	m_apm_malloclength.l;int
	m_apm_datalength.l;int
	m_apm_exponent.l;int
	m_apm_sign.l;int
EndStructure

ImportC "libmapm.lib"
	*pMM_Zero As "__imp_MM_Zero"
	*pMM_One As "__imp_MM_One"
 	*pMM_Two As "__imp_MM_Two"
	*pMM_Three As "__imp_MM_Three"
	*pMM_Four As "__imp_MM_Four"
	*pMM_Five As "__imp_MM_Five"
	*pMM_Ten As "__imp_MM_Ten"

	*pMM_PI As "__imp_MM_PI"
	*pMM_HALF_PI As "__imp_MM_HALF_PI"
	*pMM_2_PI As "__imp_MM_2_PI"
	*pMM_E As "__imp_MM_E"

	*pMM_LOG_E_BASE_10 As "__imp_MM_LOG_E_BASE_10"
	*pMM_LOG_10_BASE_E As "__imp_MM_LOG_10_BASE_E"
	*pMM_LOG_2_BASE_E As "__imp_MM_LOG_2_BASE_E"
	*pMM_LOG_3_BASE_E As "__imp_MM_LOG_3_BASE_E"

  m_apm_init()
  m_apm_free(*n.mapm)
  m_apm_free_all_mem()
  m_apm_trim_mem_usage()
  m_apm_set_string(*n.mapm,sn.s)
  m_apm_set_long(*mp.mapm, long.l)
  m_apm_set_double(*mp.mapm, dbl.d)
  m_apm_to_string(buffer.s, dplaces.l, *n.mapm)
  m_apm_to_fixpt_string(buffer.s, dplaces.l, *n.mapm)
  m_apm_to_fixpt_stringex(buffer.s, dplaces.l, *n.mapm, radix.c, separator_char.c, separator_count.l)
;  example use  
;  m_apm_to_fixpt_stringex(s,20,*m,'.',',',5)
  m_apm_to_fixpt_stringexp(dplaces.l, *n.mapm, radix.c, separator_char.c, separator_count.l)
;  example use 
;  al.l=m_apm_to_fixpt_stringexp(100,*m,'.',',',5)
;  s=PeekS(al)

  m_apm_to_integer_string(buffer.s, *n.mapm)
  m_apm_absolute_value(*r.mapm, *n.mapm)
  m_apm_negate(*r.mapm, *n.mapm)
  m_apm_copy(*r.mapm, *n.mapm)
  m_apm_round(*r.mapm, decimal_places.l, *n.mapm)
  
	m_apm_compare.l(*x.mapm, *y.mapm)
	m_apm_sign.l(*x.mapm)
	m_apm_exponent.l(*x.mapm)
	m_apm_significant_digits.l(*x.mapm)
	m_apm_is_integer.l(*x.mapm)
	m_apm_is_even.l(*x.mapm)
	m_apm_is_odd.l(*x.mapm)

	m_apm_gcd(*result.mapm, *x.mapm, *y.mapm)
	m_apm_lcm(*result.mapm, *x.mapm, *y.mapm)

	m_apm_add(*result.mapm, *x.mapm, *y.mapm)
	m_apm_subtract(*result.mapm, *x.mapm, *y.mapm)
	m_apm_multiply(*result.mapm, *x.mapm, *y.mapm)
	m_apm_divide(*result.mapm, dplaces.l, *x.mapm, *y.mapm)
	m_apm_integer_divide(*result.mapm, *x.mapm, *y.mapm)
	m_apm_integer_div_rem(*quot.mapm, *rem.mapm, *x.mapm, *y.mapm)
	m_apm_reciprocal(*result.mapm, dplaces.l, *x.mapm)
	m_apm_factorial(*result.mapm, *x.mapm)
	m_apm_floor(*result.mapm, *x.mapm)
	m_apm_ceil(*result.mapm, *x.mapm)
	m_apm_get_random(*result.mapm)
	m_apm_set_random_seed(s.s)

	m_apm_sqrt(*result.mapm, dplaces.l, *x.mapm)
	m_apm_cbrt(*result.mapm, dplaces.l, *x.mapm)
	m_apm_log(*result.mapm, dplaces.l, *x.mapm)
	m_apm_log10(*result.mapm, dplaces.l, *x.mapm)
	m_apm_exp(*result.mapm, dplaces.l, *x.mapm)
	m_apm_pow(*result.mapm, dplaces.l, *x.mapm, *y.mapm)
	m_apm_integer_pow(*result.mapm, dplaces.l, *x.mapm, y.l)
	m_apm_integer_pow_nr(*result.mapm, *x.mapm, y.l)

	m_apm_sin_cos(*sin.mapm, *cos.mapm, dplaces.l, *x.mapm)
	m_apm_sin(*result.mapm, dplaces.l, *x.mapm)
	m_apm_cos(*result.mapm, dplaces.l, *x.mapm)
	m_apm_tan(*result.mapm, dplaces.l, *x.mapm)
	m_apm_arcsin(*result.mapm, dplaces.l, *x.mapm)
	m_apm_arccos(*result.mapm, dplaces.l, *x.mapm)
	m_apm_arctan(*result.mapm, dplaces.l, *x.mapm)
	m_apm_arctan2(*result.mapm, dplaces.l, *x.mapm, *y.mapm)

	m_apm_sinh(*result.mapm, dplaces.l, *x.mapm)
	m_apm_cosh(*result.mapm, dplaces.l, *x.mapm)
	m_apm_tanh(*result.mapm, dplaces.l, *x.mapm)
	m_apm_arcsinh(*result.mapm, dplaces.l, *x.mapm)
	m_apm_arccosh(*result.mapm, dplaces.l, *x.mapm)
	m_apm_arctanh(*result.mapm, dplaces.l, *x.mapm)
EndImport

	*MM_Zero           = PeekL(*pMM_Zero)
	*MM_One            = PeekL(*pMM_One)
 	*MM_Two            = PeekL(*pMM_Two)
	*MM_Three          = PeekL(*pMM_Three)
	*MM_Four           = PeekL(*pMM_Four)
	*MM_Five           = PeekL(*pMM_Five)
	*MM_Ten            = PeekL(*pMM_Ten)

	*MM_PI             = PeekL(*pMM_PI)
	*MM_HALF_PI        = PeekL(*pMM_HALF_PI)
	*MM_2_PI           = PeekL(*pMM_2_PI)
	*MM_E              = PeekL(*pMM_E)

	*MM_LOG_E_BASE_10  = PeekL(*pMM_LOG_E_BASE_10)
	*MM_LOG_10_BASE_E  = PeekL(*pMM_LOG_10_BASE_E)
	*MM_LOG_2_BASE_E   = PeekL(*pMM_LOG_2_BASE_E)
	*MM_LOG_3_BASE_E   = PeekL(*pMM_LOG_3_BASE_E)

OpenConsole()

*n.mapm
*m.mapm
*k.mapm
*n=m_apm_init()
*m=m_apm_init()
*k=m_apm_init()

;<<<<<<<< this works OK >>>>>>>>>
s.s=Space(512)
m_apm_to_string(s, 100, PeekL(*pMM_PI))
PrintN(s)

;<<<<<<<< why does the following not work? >>>>>>>>>
s.s=Space(512)
m_apm_to_string(s, 100, *MM_PI)
PrintN(s)

Input()

m_apm_free(*k)
m_apm_free(*m)
m_apm_free(*n)
CloseConsole()

Posted: Fri May 01, 2009 11:59 pm
by Arctic Fox
Thanks for your response jack!
No POLINK-error anymore :D
jack wrote:but this don't work, why?

Code: Select all

*MM_PI             = PeekL(*pMM_PI)
m_apm_to_string(s, 100, *MM_PI)
The debugger says that PeekL(*pMM_PI) is just ZERO - I am sorry, but I have no idea of the cause of the problem so far :(

By the way I have been experimenting with the "old library" :wink:
It seems to have a limited memory of four bytes per APM-number - is there any way to extend the limit or even remove it?

Posted: Sat May 02, 2009 6:02 am
by thearr
but there's a problem, the following line works

Code: Select all

m_apm_to_string(s, 100, PeekL(*pMM_PI))
but this don't work, why?

Code: Select all

*MM_PI             = PeekL(*pMM_PI)
m_apm_to_string(s, 100, *MM_PI)

Try this code:

Code: Select all

MM_PI = PeekL(*pMM_PI)
m_apm_to_string(s, 100, @MM_PI)

Posted: Sat May 02, 2009 2:23 pm
by Arctic Fox
thearr wrote:Try this code:

Code: Select all

MM_PI = PeekL(*pMM_PI)
m_apm_to_string(s, 100, @MM_PI)
That might work, however this is getting strange.
Try these examples, which use thearr's solution. The first one fails, while the second one returns a lot of zeroes.

Fails:

Code: Select all

MM_PI = PeekL(*pMM_PI)

*n.mapm
*m.mapm
*k.mapm
*n=m_apm_init()
*m=m_apm_init()
*k=m_apm_init()

;<<<<<<<< this works OK >>>>>>>>>
s.s=Space(512)
m_apm_to_string(s, 100, PeekL(*pMM_PI))
PrintN(s)

;<<<<<<<< why does the following not work? >>>>>>>>>
s.s=Space(512)
m_apm_to_string(s, 100, @MM_PI)
PrintN(s)
Works, but returns zeroes:

Code: Select all

*n.mapm
*m.mapm
*k.mapm
*n=m_apm_init()
*m=m_apm_init()
*k=m_apm_init()

;<<<<<<<< this works OK >>>>>>>>>
s.s=Space(512)
m_apm_to_string(s, 100, PeekL(*pMM_PI))
PrintN(s)

;<<<<<<<< why does the following not work? >>>>>>>>>
s.s=Space(512)
MM_PI = PeekL(*pMM_PI)
m_apm_to_string(s, 100, @MM_PI)
PrintN(s)

Posted: Sat May 02, 2009 11:41 pm
by jack
I think I found the solution, you need to access the constants after an m_apm_init()

this seems to work, perhaps including the constant initialization in the dllmain would fix it.

Code: Select all

Structure  mapm;M_APM_struct
	*m_apm_data.c
	m_apm_id.l
	m_apm_refcount.l;int
	m_apm_malloclength.l;int
	m_apm_datalength.l;int
	m_apm_exponent.l;int
	m_apm_sign.l;int
EndStructure

ImportC "libmapm.lib";"mapm.lib"
	*pMM_Zero As "__imp_MM_Zero"
	*pMM_One As "__imp_MM_One"
 	*pMM_Two As "__imp_MM_Two"
	*pMM_Three As "__imp_MM_Three"
	*pMM_Four As "__imp_MM_Four"
	*pMM_Five As "__imp_MM_Five"
	*pMM_Ten As "__imp_MM_Ten"

	*pMM_PI As "__imp_MM_PI"
	*pMM_HALF_PI As "__imp_MM_HALF_PI"
	*pMM_2_PI As "__imp_MM_2_PI"
	*pMM_E As "__imp_MM_E"

	*pMM_LOG_E_BASE_10 As "__imp_MM_LOG_E_BASE_10"
	*pMM_LOG_10_BASE_E As "__imp_MM_LOG_10_BASE_E"
	*pMM_LOG_2_BASE_E As "__imp_MM_LOG_2_BASE_E"
	*pMM_LOG_3_BASE_E As "__imp_MM_LOG_3_BASE_E"

  m_apm_init()
  m_apm_free(*n.mapm)
  m_apm_free_all_mem()
  m_apm_trim_mem_usage()
  m_apm_set_string(*n.mapm,sn.s)
  m_apm_set_long(*mp.mapm, long.l)
  m_apm_set_double(*mp.mapm, dbl.d)
  m_apm_to_string(buffer.s, dplaces.l, *n.mapm)
  m_apm_to_fixpt_string(buffer.s, dplaces.l, *n.mapm)
  m_apm_to_fixpt_stringex(buffer.s, dplaces.l, *n.mapm, radix.c, separator_char.c, separator_count.l)
;  example use  
;  m_apm_to_fixpt_stringex(s,20,*m,'.',',',5)
  m_apm_to_fixpt_stringexp(dplaces.l, *n.mapm, radix.c, separator_char.c, separator_count.l)
;  example use 
;  al.l=m_apm_to_fixpt_stringexp(100,*m,'.',',',5)
;  s=PeekS(al)

  m_apm_to_integer_string(buffer.s, *n.mapm)
  m_apm_absolute_value(*r.mapm, *n.mapm)
  m_apm_negate(*r.mapm, *n.mapm)
  m_apm_copy(*r.mapm, *n.mapm)
  m_apm_round(*r.mapm, decimal_places.l, *n.mapm)
  
	m_apm_compare.l(*x.mapm, *y.mapm)
	m_apm_sign.l(*x.mapm)
	m_apm_exponent.l(*x.mapm)
	m_apm_significant_digits.l(*x.mapm)
	m_apm_is_integer.l(*x.mapm)
	m_apm_is_even.l(*x.mapm)
	m_apm_is_odd.l(*x.mapm)

	m_apm_gcd(*result.mapm, *x.mapm, *y.mapm)
	m_apm_lcm(*result.mapm, *x.mapm, *y.mapm)

	m_apm_add(*result.mapm, *x.mapm, *y.mapm)
	m_apm_subtract(*result.mapm, *x.mapm, *y.mapm)
	m_apm_multiply(*result.mapm, *x.mapm, *y.mapm)
	m_apm_divide(*result.mapm, dplaces.l, *x.mapm, *y.mapm)
	m_apm_integer_divide(*result.mapm, *x.mapm, *y.mapm)
	m_apm_integer_div_rem(*quot.mapm, *rem.mapm, *x.mapm, *y.mapm)
	m_apm_reciprocal(*result.mapm, dplaces.l, *x.mapm)
	m_apm_factorial(*result.mapm, *x.mapm)
	m_apm_floor(*result.mapm, *x.mapm)
	m_apm_ceil(*result.mapm, *x.mapm)
	m_apm_get_random(*result.mapm)
	m_apm_set_random_seed(s.s)

	m_apm_sqrt(*result.mapm, dplaces.l, *x.mapm)
	m_apm_cbrt(*result.mapm, dplaces.l, *x.mapm)
	m_apm_log(*result.mapm, dplaces.l, *x.mapm)
	m_apm_log10(*result.mapm, dplaces.l, *x.mapm)
	m_apm_exp(*result.mapm, dplaces.l, *x.mapm)
	m_apm_pow(*result.mapm, dplaces.l, *x.mapm, *y.mapm)
	m_apm_integer_pow(*result.mapm, dplaces.l, *x.mapm, y.l)
	m_apm_integer_pow_nr(*result.mapm, *x.mapm, y.l)

	m_apm_sin_cos(*sin.mapm, *cos.mapm, dplaces.l, *x.mapm)
	m_apm_sin(*result.mapm, dplaces.l, *x.mapm)
	m_apm_cos(*result.mapm, dplaces.l, *x.mapm)
	m_apm_tan(*result.mapm, dplaces.l, *x.mapm)
	m_apm_arcsin(*result.mapm, dplaces.l, *x.mapm)
	m_apm_arccos(*result.mapm, dplaces.l, *x.mapm)
	m_apm_arctan(*result.mapm, dplaces.l, *x.mapm)
	m_apm_arctan2(*result.mapm, dplaces.l, *x.mapm, *y.mapm)

	m_apm_sinh(*result.mapm, dplaces.l, *x.mapm)
	m_apm_cosh(*result.mapm, dplaces.l, *x.mapm)
	m_apm_tanh(*result.mapm, dplaces.l, *x.mapm)
	m_apm_arcsinh(*result.mapm, dplaces.l, *x.mapm)
	m_apm_arccosh(*result.mapm, dplaces.l, *x.mapm)
	m_apm_arctanh(*result.mapm, dplaces.l, *x.mapm)
EndImport

	*MM_Zero           = PeekL(*pMM_Zero)
	*MM_One            = PeekL(*pMM_One)
 	*MM_Two            = PeekL(*pMM_Two)
	*MM_Three          = PeekL(*pMM_Three)
	*MM_Four           = PeekL(*pMM_Four)
	*MM_Five           = PeekL(*pMM_Five)
	*MM_Ten            = PeekL(*pMM_Ten)

	*MM_PI             = PeekL(*pMM_PI)
	*MM_HALF_PI        = PeekL(*pMM_HALF_PI)
	*MM_2_PI           = PeekL(*pMM_2_PI)
	*MM_E              = PeekL(*pMM_E)

	*MM_LOG_E_BASE_10  = PeekL(*pMM_LOG_E_BASE_10)
	*MM_LOG_10_BASE_E  = PeekL(*pMM_LOG_10_BASE_E)
	*MM_LOG_2_BASE_E   = PeekL(*pMM_LOG_2_BASE_E)
	*MM_LOG_3_BASE_E   = PeekL(*pMM_LOG_3_BASE_E)


OpenConsole()

*n.mapm
*m.mapm
*k.mapm
*n=m_apm_init()
*m=m_apm_init()
*k=m_apm_init()

s.s=Space(512)
m_apm_to_string(s, 100, *MM_PI)
PrintN(s)


Input()

m_apm_free(*k)
m_apm_free(*m)
m_apm_free(*n)
CloseConsole()

Posted: Sun May 03, 2009 12:18 am
by Arctic Fox
That sounds very good :D (though I don't know how to include the constant initialization in the dll :lol:)
So if I understand it correctly, the constants are only available after using m_apm_init() :?:

Posted: Sun May 03, 2009 12:40 am
by jack
at the moment yes, but let me try and include the constant initialization into a dllmain and see what happens, (it may be a few days, am rather lazy at the moment)

Posted: Sun May 03, 2009 12:55 am
by Arctic Fox
jack wrote:at the moment yes, but let me try and include the constant initialization into a dllmain and see what happens, (it may be a few days, am rather lazy at the moment)
That's okay with me, just take your time :D

Have you got an answer for my other question? (here it is again, if you haven't seen it yet :lol:)
It seems to have a limited memory of four bytes per APM-number - is there any way to extend the limit or even remove it?

Posted: Sun May 03, 2009 1:12 am
by jack
my appologies Arctic Fox, not sure I understand your question, the APM-variables are pointers that point where the number is stored, in a 32-bit system the pointer is 4 bytes.

Posted: Sun May 03, 2009 1:22 am
by Arctic Fox
Oops, seems to be my fault :oops:
It's the debugger, which won't show more than 4096 characters, it just truncates the number and leaves [...]. I didn't understand that at the beginning.

Never mind my question then :lol:
And thanks for the information about pointers - got that written down.

Posted: Sun May 03, 2009 2:37 am
by jack
Arctic Fox, I went ahead and added a dllmain, and it seems to work OK.

here's the modified MKALLMGW.BAT

Code: Select all

rem
rem  mkallmgw.bat
rem
rem  Build batch file for MINGW compiler
rem  Tested with version mingw-1.0.1-20010726
rem  (This package contains GCC version 2.95.3)
rem
rem  also tested with gcc 3.2    (mingw special 20020817-1)
rem  also tested with gcc 3.2.3  (mingw special 20030504-1)
rem
rem  note that each file is compiled separately
rem  since this compiler did not support wildcards
rem  (map*.c) on my system.
rem
rem  compile the MAPM library files
rem
del map*.o
rem
gcc -v
rem
gcc -c -Wall -O2 mapm_add.c
gcc -c -Wall -O2 mapm_cpi.c
gcc -c -Wall -O2 mapm_div.c
gcc -c -Wall -O2 mapm_exp.c
gcc -c -Wall -O2 mapm_fam.c
gcc -c -Wall -O2 mapm_fft.c
gcc -c -Wall -O2 mapm_flr.c
gcc -c -Wall -O2 mapm_fpf.c
gcc -c -Wall -O2 mapm_gcd.c
gcc -c -Wall -O2 mapm_log.c
gcc -c -Wall -O2 mapm_lg2.c
gcc -c -Wall -O2 mapm_lg3.c
gcc -c -Wall -O2 mapm_lg4.c
gcc -c -Wall -O2 mapm_mul.c
gcc -c -Wall -O2 mapm_pow.c
gcc -c -Wall -O2 mapm_rcp.c
gcc -c -Wall -O2 mapm_rnd.c
gcc -c -Wall -O2 mapm_set.c
gcc -c -Wall -O2 mapm_sin.c
gcc -c -Wall -O2 mapm5sin.c
gcc -c -Wall -O2 mapmasin.c
gcc -c -Wall -O2 mapmasn0.c
gcc -c -Wall -O2 mapmcbrt.c
gcc -c -Wall -O2 mapmcnst.c
gcc -c -Wall -O2 mapmfact.c
gcc -c -Wall -O3 mapmfmul.c
gcc -c -Wall -O2 mapmgues.c
gcc -c -Wall -O2 mapmhasn.c
gcc -c -Wall -O2 mapmhsin.c
gcc -c -Wall -O2 mapmipwr.c
gcc -c -Wall -O2 mapmistr.c
gcc -c -Wall -O2 mapmpwr2.c
gcc -c -Wall -O2 mapmrsin.c
gcc -c -Wall -O2 mapmsqrt.c
gcc -c -Wall -O2 mapmstck.c
gcc -c -Wall -O3 mapmutil.c
gcc -c -Wall -O2 mapmutl1.c
gcc -c -Wall -O2 mapmutl2.c
gcc -c -Wall -O2 dllmain.c
rem
rem
rem build the library and delete object files
rem
del libmapm.a
del mapm.dll
ar rc libmapm.a map*.o
gcc -shared -o mapm.dll map*.o dllmain.o
del map*.o
rem
rem
rem  build the 4 demo programs
rem
rem
gcc -Wall -O2 -o calc.exe calc.c libmapm.a -s -lm
gcc -Wall -O2 -o validate.exe validate.c libmapm.a -s -lm
gcc -Wall -O2 -o primenum.exe primenum.c libmapm.a -s -lm
rem
gcc -Wall -O2 -o cpp_demo.exe cpp_demo.cpp libmapm.a -s -lm -lstdc++
rem
rem
rem
and here's dllmain.c

Code: Select all

#include <windows.h>
#include "M_APM_LC.H"

BOOL WINAPI
DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
{
    switch (dwReason)
    {
        case DLL_PROCESS_ATTACH:

            M_init_trig_globals();
            break;

        case DLL_PROCESS_DETACH:
            M_free_all_cnst();
            break;

        case DLL_THREAD_ATTACH:
            // Code to run when a thread is created during the DLL's lifetime
            break;

        case DLL_THREAD_DETACH:
            // Code to run when a thread ends normally.
            break;
    }
    return TRUE;
}

Posted: Sun May 03, 2009 2:58 am
by Arctic Fox
Nice one jack! Not so lazy after all, eh? :wink:
Have you got an example with the changes? (I am lazy, hehe)