⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nu_math.c

📁 nucleus 文件系统,内核和彩色图形系统,在小系统上非常好用
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************/
/*                                                                       */
/*        Copyright (c) 1999 Accelerated Technology, Inc.                */
/*                                                                       */
/* PROPRIETARY RIGHTS of Accelerated Technology are involved in the      */
/* subject matter of this material.  All manufacturing, reproduction,    */
/* use, and sales rights pertaining to this subject matter are governed  */
/* by the license agreement.  The recipient of this software implicitly  */
/* accepts the terms of the license.                                     */
/*                                                                       */
/*************************************************************************/

/*************************************************************************/
/*                                                                       */
/* FILE NAME                                            VERSION          */
/*                                                                       */
/*      Nu_math.c                                        1.9             */
/*                                                                       */
/* COMPONENT                                                             */
/*                                                                       */
/*      All                                                              */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*		Fixed-pont math functions										 */
/*                                                                       */
/* AUTHOR                                                                */
/*                                                                       */
/*      Giac Dinh , Accelerated Technology, Inc.                         */
/*                                                                       */
/* DATA STRUCTURES                                                       */
/*                                                                       */
/*      None                                                             */
/*                                                                       */
/* FUNCTIONS                                                             */
/*                                                                       */
/*      None                                                             */
/*                                                                       */
/* DEPENDENCIES                                                          */
/*                                                                       */
/*      None                                                             */
/*                                                                       */
/* HISTORY                                                               */
/*                                                                       */
/*         NAME            DATE                    REMARKS               */
/*                                                                       */
/*                                                                       */
/*************************************************************************/

#include "Nu_math.h"

#ifndef CPU_FLOAT

long Fix_mul( long first, long second)
{
	long result;
	unsigned long ai, bi, af, bf, item, tem;
	short sign = 1;
	
	if (first < 0)
	{
		first = -first;
		sign *= -1;
	}
	if(second < 0)	
	{
		second = -second;
		sign *= -1;
	}

	af = (unsigned long) (first & 0xFFFF);
	bf = (unsigned long) (second & 0xFFFF);
	ai = (unsigned long) (first >> 16);
	bi = (unsigned long) (second >> 16);

	item = ai * bi;
	if(item > 32767)
		return(0x7FFFFFFF * sign); /* Number is too big */

	tem = af * bf;
	item = (item << 16) + (af * bi) + (ai * bf) + (tem >> 16);
	if(item >= 0x80000000)
		return(0x7FFFFFFF * sign); /* Number is too big */

	result = sign * ((long) item);
	return(result);
}

long Fix_sqrt(long root)
{
	long Fix_div(long,long);
	int i;
	unsigned long init, tem;
	
	if(root <= 0)
		return(0);

	init = (1 << 16);
	for(i = 0; i < 10; i++)
	{
		tem = ((init + (Fix_div(root,init))) >> 1);
		if (init > tem)
		{
			if ((init - tem) < 0x0080) break;
		}
		else
		{
			if ((tem - init) < 0x0080) break;
		}
		init = tem;
	}
	return(tem);		
}

long Fix_div(long a, long b)
{
	short sign = 1;
	unsigned long aa, bb;
	long result = 0;
	int i;

	if((a == 0) || (b == 0))
		return(0);

	if(a < 0)
	{
		a = -a;
		sign *= -1;
	}
	if(b < 0)
	{
		b = -b;
		sign *= -1;
	}

	aa = (unsigned long) a;
	bb = (unsigned long) b;

	if(aa >= bb)
	{	/* get integer part */
		result = (aa / bb);
		aa -= (result * bb);
	}

	/* now get fractional part by comparison method */
	for (i = 0; i < 16; i++)
	{
		result = (result << 1);
		aa = (aa << 1);
		if (bb > aa) continue;

		result += 1;
		aa -= bb;
		if (!(aa))
		{	/* done early */
			result = (result << (15 - i));
			break;
		}
	}

	return(result * sign);
}

/*
Function ISIN RETURNs a double-word fixed point fraction of the sine of ANGLE 
which is specified in integer tenth of degrees (0-3599 = 0 to 359.9 degrees). 
The RETURNed word value in ax is an unsigned integer fraction of the sine of 
ANGLE with an implied decimal point to the left of the high order bit. 
Register bx is set to 0000h for positive sine values, or to FF00h for 
negative sine values.  AX is RETURNed with an unsigned positive fraction 
value for the sine/cosine function.  BX indicates whether the sine/cosine is 
positive or negative.  For example:

		 bx . ax
	        ---- ----
		0000.FFFF	= +0.99999 (+1.0)
		0000.8000	= +0.5
		0000.4000	= +0.25
		0000.2000	= +0.125
		0000.0000	=  0
		FF00.2000	= -0.125
		FF00.8000	= -0.5
		FF00.4000	= -0.25
		FF00.FFFF	= -0.99999 (-1.0)

Sine values are extracted from the sin lookup table based on the following 
identities:

  sin(angle) =	000.0-089.9	   sin(angle)
		090.0-179.9	 sin(180-angle)
		180.0-269.9	-sin(angle-180)
		270.0-359.9	-sin(360-angle)
  cos(angle) =  sin(angle+90)

The sinTbl array defines the value for each integer angle to an accuracy of 
0.0000152 (1/64636).  Linear interpolation is used to compute tenth of degree 
angle increments.
*/

long iCos(long Angle)
{
long iSin(long);
	if(Angle == 0)
		return(0x0000FFFF);
	return(iSin(Angle + 900));
}

long iSin(long Angle)
{
	short temAngle, temAngleFract, sign = 1;
	long result;

unsigned short sinTbl[]= {
		0x0000,  0x0478,  0x08EF,  0x0D66,  0x11DC,	/*sin  0- 4 */
		0x1650,  0x1AC2,  0x1F33,  0x23A1,  0x280C,	/*sin  5- 9 */
		0x2C74,  0x30D9,  0x353A,  0x3996,  0x3DEF,	/*sin 10-14 */
		0x4242,  0x4690,  0x4AD9,  0x4F1C,  0x5358,	/*sin 15-19 */
		0x578F,  0x5BBE,  0x5FE6,  0x6407,  0x6820,	/*sin 20-24 */
		0x6C31,  0x7039,  0x7439,  0x782F,  0x7C1C,	/*sin 25-29 */
		0x8000,  0x83DA,  0x87A9,  0x8B6D,  0x8F27,	/*sin 30-34 */
		0x92D6,  0x9679,  0x9A11,  0x9D9C,  0xA11B,	/*sin 35-39 */
		0xA48E,  0xA7F3,  0xAB4C,  0xAE97,  0xB1D5,	/*sin 40-44 */
		0xB505,  0xB827,  0xBB3A,  0xBE3F,  0xC135,	/*sin 45-49 */
		0xC41B,  0xC6F3,  0xC9BB,  0xCC73,  0xCF1C,	/*sin 50-54 */
		0xD1B4,  0xD43C,  0xD6B3,  0xD91A,  0xDB6F,	/*sin 55-59 */
		0xDDB4,  0xDFE7,  0xE209,  0xE419,  0xE617,	/*sin 60-64 */
		0xE804,  0xE9DE,  0xEBA6,  0xED5C,  0xEEFF,	/*sin 65-69 */
		0xF090,  0xF20E,  0xF378,  0xF4D0,  0xF615,	/*sin 70-74 */
		0xF747,  0xF865,  0xF970,  0xFA68,  0xFB4C,	/*sin 75-79 */
		0xFC1C,  0xFCD9,  0xFD82,  0xFE18,  0xFE99,	/*sin 80-84 */
		0xFF07,  0xFF60,  0xFFA6,  0xFFD8,  0xFFF6,	/*sin 85-89 */
		0xFFFF};									/*sin 90 */


	if(Angle == 0)
		return(0);

	while(Angle < 0)
		Angle += 3600;

	while(Angle >= 3600)
		Angle -= 3600;
	
	if(Angle > 2700) 
	{
		Angle = 3600 - Angle;
		sign = -1;
	}
	else if(Angle > 1800)
	{
		Angle = Angle - 1800;
		sign = -1;
	}
	else if(Angle > 900)
	{
		Angle = 1800 - Angle;
	}

	temAngle = Angle / 10;
	temAngleFract = Angle - (10 * temAngle);
	
	result = (long) sinTbl[temAngle];
	if (temAngleFract)
	{
		result += ((temAngleFract * ((long) sinTbl[temAngle + 1]
			- result)) / 10);
	}

	return(sign * result);
}

long Nu_asin(long radian)
{
unsigned short sinTbl[]= {
		0x0000,  0x0478,  0x08EF,  0x0D66,  0x11DC,	/*sin  0- 4 */
		0x1650,  0x1AC2,  0x1F33,  0x23A1,  0x280C,	/*sin  5- 9 */
		0x2C74,  0x30D9,  0x353A,  0x3996,  0x3DEF,	/*sin 10-14 */
		0x4242,  0x4690,  0x4AD9,  0x4F1C,  0x5358,	/*sin 15-19 */
		0x578F,  0x5BBE,  0x5FE6,  0x6407,  0x6820,	/*sin 20-24 */
		0x6C31,  0x7039,  0x7439,  0x782F,  0x7C1C,	/*sin 25-29 */
		0x8000,  0x83DA,  0x87A9,  0x8B6D,  0x8F27,	/*sin 30-34 */
		0x92D6,  0x9679,  0x9A11,  0x9D9C,  0xA11B,	/*sin 35-39 */
		0xA48E,  0xA7F3,  0xAB4C,  0xAE97,  0xB1D5,	/*sin 40-44 */
		0xB505,  0xB827,  0xBB3A,  0xBE3F,  0xC135,	/*sin 45-49 */
		0xC41B,  0xC6F3,  0xC9BB,  0xCC73,  0xCF1C,	/*sin 50-54 */
		0xD1B4,  0xD43C,  0xD6B3,  0xD91A,  0xDB6F,	/*sin 55-59 */
		0xDDB4,  0xDFE7,  0xE209,  0xE419,  0xE617,	/*sin 60-64 */
		0xE804,  0xE9DE,  0xEBA6,  0xED5C,  0xEEFF,	/*sin 65-69 */
		0xF090,  0xF20E,  0xF378,  0xF4D0,  0xF615,	/*sin 70-74 */
		0xF747,  0xF865,  0xF970,  0xFA68,  0xFB4C,	/*sin 75-79 */
		0xFC1C,  0xFCD9,  0xFD82,  0xFE18,  0xFE99,	/*sin 80-84 */
		0xFF07,  0xFF60,  0xFFA6,  0xFFD8,  0xFFF6,	/*sin 85-89 */
		0xFFFF};									/*sin 90 */
	unsigned short compare, i = 1;

	compare = (unsigned short) (radian & 0x0000FFFF);
	
	while(sinTbl[i] < compare)
	{
		i++;
	}

	compare = 10 * (sinTbl[i] - compare);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -