//***********************************************************************
// FileDescription:     Fast Algorithms Library For Huge Integer.
// FileVersion:         2007-12-08
// ProductVersion:      8, 0, 0, 0
//
// Portability:         ANSI C++
// Base Classes:        None.
// Related Document:    HugeCalc.chm
//
// Copyright (c) 1992-2007 by Guo XianQiang. All rights reserved.
//
//
// Web: http://www.emath.ac.cn/hugecalc/
// BBS: http://bbs.emath.ac.cn/
// E-Mail: gxqcn@163.com; HugeCalc@Gmail.com
//***********************************************************************

// If you find any bug or you want to add some useful function
// please email to me. Redistribution and use in source are
// permitted provided that: source distributions retain this
// entire copyright notice and comment.
// 如果你在使用中发现BUG或添加了功能,请Email我。
// 你可以使用与发布该文件,但不得进行商业用途。
// 你的发布要包含完整的本文件头。

/*
附加说明:

    1、调用程序所在目录必须为 /CopyrightByGuoXianqiang/[../],否则 HugeCalc.dll 会拒绝任何服务。

    2、如需解除上述限制,请在 HugeCalc.chm 中进行“注册”。

    3、HugeCalc 最新正式版下载链接为:http://www.emath.ac.cn/software.htm#HugeCalc

    4、本导出接口文件可自动适应 MBCS / UNICODE 环境调用。

    5、欢迎进行各项测试,如果发现bug,请及时联系,谢谢!

    6、请务必遵守配套的 HugeCalc.chm 的相关声明!

郭先强(gxqcn@163.com; HugeCalc@Gmail.com)
2007-12-08
*/

#ifndef __cplusplus
    #error Must use C++ for HugeCalc.
#endif

#if !defined(AFX_HUGECALC_H__99330C8A_F843_4e32_876B_D0DF036B4E05__INCLUDED_)
#define AFX_HUGECALC_H__99330C8A_F843_4e32_876B_D0DF036B4E05__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include < WTYPES.H >

//add to your .cpp file:
//  #pragma message( "automatic link to ../../../HugeCalc_API/CppAPI/Lib/HugeCalc.lib" )
//  #pragma comment( lib, "../../../HugeCalc_API/CppAPI/Lib/HugeCalc.lib" )


// ================ typedef ================

#ifndef _SINT32
    #define _SINT32
    typedef INT32 SINT32;
#endif // !defined(_SINT32)

#ifndef _SINT64
    #define _SINT64
    typedef INT64 SINT64;
#endif // !defined(_SINT64)

// ================ enum ================

typedef enum tagHCLicenseLevel
{
    HC_LICENSE_NONE         = 0x00,	/* 很容易转换成 HC_LICENSE_DEMO */
    HC_LICENSE_DEMO         = 0x01,	/* 使用上略有限制 */
    HC_LICENSE_ALL          = 0x02,	/* 注册后获得单机所有权限 */
    HC_LICENSE_CUSTOM       = 0xFF,	/* 客户定制,欢迎联系洽谈 */
}HCLicenseLevel;

typedef enum tagHCErrCode
{
    HCERR_NONE              = 0,
    HCERR_NO_LICENSE        = 1,
    HCERR_USER_STOP         = 2,
    HCERR_NO_ENOUGH_MEMORY  = 3,
    HCERR_INVALID_POINTER   = 4,
    HCERR_DIV_ZERO          = 5,
    HCERR_BASE2SMALL        = 6,
    HCERR_RADIX2SMALL       = 7,
    //...
}HCErrCode;

typedef enum tagSIGN
{
    SIGN_NEG    = -1,   // Negative
    SIGN_ZERO   =  0,   // Zero
    SIGN_POS    =  1,   // Positive
}SIGN;

typedef enum tagTimerUnit
{
    TIMER_UNIT_ms   = 0,    // millisecond
    TIMER_UNIT_us   = 1,    // microsecond
    TIMER_UNIT_ns   = 2,    // millimicrosecond
}TimerUnit;

typedef enum tagFormatTime
{
    FT_HHMMSS_ms    = 0,    // "00:00:12.345"
    FT_DOT06SEC     = 1,    // "12.345678"
    FT_DOT06SECs    = 2,    // "12.345678s"
    FT_DOT06SEC_s   = 3,    // "12.345678 s"
}FormatTime;

typedef enum tagPrimality
{
    COMPOSITE       = 0,
    PROBABLY_PRIME  = 1,
    PRIME           = 2,
}PRIMALITY;

// ================ struct ================

typedef struct tagCVECTOR_UINT32
{
    CONST UINT32 * p_start;
    UINT32 u32Size;

#ifdef __cplusplus
    tagCVECTOR_UINT32( CONST UINT32 * CONST _p_start = NULL, CONST UINT32 _u32Size = 0 )
        : p_start( _p_start ), u32Size( _u32Size )
    {
    };
#endif
} CVECTOR_UINT32, FAR *PCVECTOR_UINT32;
typedef CONST CVECTOR_UINT32 FAR *LPCVECTOR_UINT32;

// ================ CONST ================

CONST BYTE FS_NORMAL        = 0x00; // normal format
CONST BYTE FS_BAND          = 0x01; // ' ' or ',' at pre 3[or4] digits from right
CONST BYTE FS_BAND_SPACE    = 0x02; // must setting "| FS_BAND"
CONST BYTE FS_SIGN          = 0x04; // even if "+"
CONST BYTE FS_SIGN_SPACE    = 0x08; // between sign and number
CONST BYTE FS_CHAR_LOWER    = 0x10; // will use [0-9a-z]; otherwise, use [0-9A-Z]
CONST BYTE FS_DEFAULT       = FS_BAND | FS_BAND_SPACE | FS_SIGN_SPACE;  // default format

#define _POW2_32    0   /* for base or radix */

#define _HC_Export_HC                   0x00000001  /* 25 functions */
#define _HC_Export_HI                   0x00000002  /* 91 functions */
#define _HC_Export_HX                   0x00000004  /* 92 functions */
#define _HC_Export_RC                   0x00000008  /* 24 functions */

#define _HC_Export_HugeCalc             0x00010000  /* 36 functions */
#define _HC_Export_CHugeInt             0x00020000  /*204 functions */
#define _HC_Export_CHugeIntX            0x00040000  /*205 functions */
#define _HC_Export_CRadixConverter      0x00080000  /* 28 functions */

#define _HC_Export_ANSI_C               0x0000FFFF  /*236 functions */
#define _HC_Export_ANSI_CPLUSPLUS       0xFFFF0000  /*473 functions */
#define _HC_Export_All                  0xFFFFFFFF  /*709 functions */

#if !( defined( UNICODE ) || defined( _UNICODE ))
    #define GetVer          GetVerA
    #define GetSN           GetSNA
    #define GetTimerStr     GetTimerStrA

    #define GetStr          GetStrA
    #define GetHexStr       GetHexStrA
    #define GetStrRadix     GetStrRadixA

    #define GetText         GetTextA
#else
    #define GetVer          GetVerW
    #define GetSN           GetSNW
    #define GetTimerStr     GetTimerStrW

    #define GetStr          GetStrW
    #define GetHexStr       GetHexStrW
    #define GetStrRadix     GetStrRadixW

    #define GetText         GetTextW
#endif


#define HUGECALC_API    WINBASEAPI /*__declspec(dllimport)*/
#define HC_API          HUGECALC_API

namespace HugeCalc
{
//  class CHugeInt;
//  class CHugeIntX;

    HC_API CONST LPCTSTR GetVer( VOID );
    HC_API CONST LPCTSTR GetSN( VOID );

    HC_API CONST HCLicenseLevel GetLicenseLevel( VOID );
    HC_API CONST UINT32 GetExportFunNums( CONST UINT32 u32Mask = _HC_Export_ANSI_CPLUSPLUS );

    HC_API CONST HCErrCode GetLastError( VOID );

    // It usefull when use multithread.
    HC_API VOID SetTerminate( CONST BOOL bTerminate = TRUE );
    HC_API CONST BOOL IsTerminated( VOID );

    HC_API VOID SeedRandom( CONST UINT32 u32Seed = 0 );

    // before calculate, pls call bEnableTimer as TRUE, and after finishing call as FALSE
    HC_API VOID ResetTimer( CONST UINT32 u32Timer = 0, CONST TimerUnit enumTimerUnit = TIMER_UNIT_us );
    HC_API VOID EnableTimer( CONST BOOL bEnableTimer = TRUE );
    HC_API CONST UINT32 GetTimer( CONST TimerUnit enumTimerUnit = TIMER_UNIT_us );
    HC_API CONST LPCTSTR GetTimerStr( CONST FormatTime enumFormatTime = FT_DOT06SEC_s );

    HC_API CONST BOOL IsPrime( CONST UINT32 u32Num );
    HC_API CONST UINT32 GetPrimePi( CONST UINT32 u32Num );
    HC_API CONST UINT32 GetPrime( CONST UINT32 u32Index );
    HC_API CONST UINT32 GetPrimeCount( CONST UINT32 u32LBound, CONST UINT32 u32UBound );
    HC_API CONST UINT32 GetPrimeList( UINT32 * CONST lpPrimeBuffer, CONST UINT32 u32BufferSize, CONST UINT32 u32LBound, CONST UINT32 u32UBound );

    // Returns the largest prime number less than the argument.
    HC_API CONST SINT32 PreviousPrime( CONST SINT32 s32Benchmark );
    // Returns the smallest prime number greater than the argument.
    HC_API CONST SINT32 NextPrime( CONST SINT32 s32Benchmark );

    // gives the Euler totient function φ(n).
    HC_API CONST UINT32 EulerPhi( CONST UINT32 n );
    // gives the Jacobi symbol(n/m).
    HC_API CONST SINT32 JacobiSymbol( CONST UINT32 n, CONST UINT32 m );
    // gives the multiplicative order of k modulo n, defined as the smallest integer x such that k^x ≡ 1 mod n.
    HC_API CONST UINT32 MultiplicativeOrder( CONST UINT32 k, CONST UINT32 n );
    // give a primitive root of n, where n is a prime power or twice a prime power.
    HC_API CONST UINT32 PrimitiveRoot( CONST UINT32 n );

    // Greatest Common Divisor
    HC_API CONST UINT32 Gcd( CONST UINT32 u32Num1, CONST UINT32 u32Num2 );
    HC_API CONST UINT32 Gcd( CONST SINT32 s32Num, CONST UINT32 u32Num );
    HC_API CONST UINT32 Gcd( CONST UINT32 u32Num, CONST SINT32 s32Num );
    HC_API CONST UINT32 Gcd( CONST SINT32 s32Num1, CONST SINT32 s32Num2 );

    HC_API CONST UINT32 Gcd( CONST CVECTOR_UINT32& vU32Num );

    // GcdEx: g = GcdEx( x, y, u, v ) = u * x + v * y. g is always positive, even if one or both of u and v are negative.
    HC_API CONST UINT32 GcdEx( SINT32 &x, SINT32 &y, CONST SINT32 u, CONST SINT32 v );

    // InvertMod: x = InvertMod( b, m ) && !(!x) <==> ( b * x ) mod m = 1
    HC_API CONST UINT32 InvertMod( CONST UINT32 u32InvertBase, CONST UINT32 u32Mod );

    // Lowest Common Multiple
    HC_API CONST UINT64 Lcm( CONST UINT32 u32Num1, CONST UINT32 u32Num2 );
    HC_API CONST UINT64 Lcm( CONST SINT32 s32Num, CONST UINT32 u32Num );
    HC_API CONST UINT64 Lcm( CONST UINT32 u32Num, CONST SINT32 s32Num );
    HC_API CONST UINT64 Lcm( CONST SINT32 s32Num1, CONST SINT32 s32Num2 );

    // PowMod
    HC_API CONST UINT32 PowMod( CONST UINT32 u32Base, CONST UINT32 u32Exp, CONST UINT32 u32Mod );
    HC_API CONST UINT32 PowMod( CONST UINT32 u32Base, CONST SINT32 s32Exp, CONST UINT32 u32Mod );
}

using namespace HugeCalc;

#endif // !defined(AFX_HUGECALC_H__99330C8A_F843_4e32_876B_D0DF036B4E05__INCLUDED_)