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

📄 convert.c

📁 linux0.02源代码用于研究linux操作系统
💻 C
字号:
/* * linux/kernel/math/convert.c * * (C) 1991 Linus Torvalds */#include <linux/math_emu.h>/* * NOTE!!! There is some "non-obvious" optimisations in the temp_to_long * and temp_to_short conversion routines: don't touch them if you don't * know what's going on. They are the adding of one in the rounding: the * overflow bit is also used for adding one into the exponent. Thus it * looks like the overflow would be incorrectly handled, but due to the * way the IEEE numbers work, things are correct. * * There is no checking for total overflow in the conversions, though (ie * if the temp-real number simply won't fit in a short- or long-real.) */void short_to_temp(const short_real * a, temp_real * b){	if (!(*a & 0x7fffffff)) {		b->a = b->b = 0;		if (*a)			b->exponent = 0x8000;		else			b->exponent = 0;		return;	}	b->exponent = ((*a>>23) & 0xff)-127+16383;	if (*a<0)		b->exponent |= 0x8000;	b->b = (*a<<8) | 0x80000000;	b->a = 0;}void long_to_temp(const long_real * a, temp_real * b){	if (!a->a && !(a->b & 0x7fffffff)) {		b->a = b->b = 0;		if (a->b)			b->exponent = 0x8000;		else			b->exponent = 0;		return;	}	b->exponent = ((a->b >> 20) & 0x7ff)-1023+16383;	if (a->b<0)		b->exponent |= 0x8000;	b->b = 0x80000000 | (a->b<<11) | (((unsigned long)a->a)>>21);	b->a = a->a<<11;}void temp_to_short(const temp_real * a, short_real * b){	if (!(a->exponent & 0x7fff)) {		*b = (a->exponent)?0x80000000:0;		return;	}	*b = ((((long) a->exponent)-16383+127) << 23) & 0x7f800000;	if (a->exponent < 0)		*b |= 0x80000000;	*b |= (a->b >> 8) & 0x007fffff;	switch (ROUNDING) {		case ROUND_NEAREST:			if ((a->b & 0xff) > 0x80)				++*b;			break;		case ROUND_DOWN:			if ((a->exponent & 0x8000) && (a->b & 0xff))				++*b;			break;		case ROUND_UP:			if (!(a->exponent & 0x8000) && (a->b & 0xff))				++*b;			break;	}}void temp_to_long(const temp_real * a, long_real * b){	if (!(a->exponent & 0x7fff)) {		b->a = 0;		b->b = (a->exponent)?0x80000000:0;		return;	}	b->b = (((0x7fff & (long) a->exponent)-16383+1023) << 20) & 0x7ff00000;	if (a->exponent < 0)		b->b |= 0x80000000;	b->b |= (a->b >> 11) & 0x000fffff;	b->a = a->b << 21;	b->a |= (a->a >> 11) & 0x001fffff;	switch (ROUNDING) {		case ROUND_NEAREST:			if ((a->a & 0x7ff) > 0x400)				__asm__("addl $1,%0 ; adcl $0,%1"					:"=r" (b->a),"=r" (b->b)					:"0" (b->a),"1" (b->b));			break;		case ROUND_DOWN:			if ((a->exponent & 0x8000) && (a->b & 0xff))				__asm__("addl $1,%0 ; adcl $0,%1"					:"=r" (b->a),"=r" (b->b)					:"0" (b->a),"1" (b->b));			break;		case ROUND_UP:			if (!(a->exponent & 0x8000) && (a->b & 0xff))				__asm__("addl $1,%0 ; adcl $0,%1"					:"=r" (b->a),"=r" (b->b)					:"0" (b->a),"1" (b->b));			break;	}}void real_to_int(const temp_real * a, temp_int * b){	int shift =  16383 + 63 - (a->exponent & 0x7fff);	unsigned long underflow;	b->a = b->b = underflow = 0;	b->sign = (a->exponent < 0);	if (shift < 0) {		set_OE();		return;	}	if (shift < 32) {		b->b = a->b; b->a = a->a;	} else if (shift < 64) {		b->a = a->b; underflow = a->a;		shift -= 32;	} else if (shift < 96) {		underflow = a->b;		shift -= 64;	} else		return;	__asm__("shrdl %2,%1,%0"		:"=r" (underflow),"=r" (b->a)		:"c" ((char) shift),"0" (underflow),"1" (b->a));	__asm__("shrdl %2,%1,%0"		:"=r" (b->a),"=r" (b->b)		:"c" ((char) shift),"0" (b->a),"1" (b->b));	__asm__("shrl %1,%0"		:"=r" (b->b)		:"c" ((char) shift),"0" (b->b));	switch (ROUNDING) {		case ROUND_NEAREST:			__asm__("addl %4,%5 ; adcl $0,%0 ; adcl $0,%1"				:"=r" (b->a),"=r" (b->b)				:"0" (b->a),"1" (b->b)				,"r" (0x7fffffff + (b->a & 1))				,"m" (*&underflow));			break;		case ROUND_UP:			if (!b->sign && underflow)				__asm__("addl $1,%0 ; adcl $0,%1"					:"=r" (b->a),"=r" (b->b)					:"0" (b->a),"1" (b->b));			break;		case ROUND_DOWN:			if (b->sign && underflow)				__asm__("addl $1,%0 ; adcl $0,%1"					:"=r" (b->a),"=r" (b->b)					:"0" (b->a),"1" (b->b));			break;	}}void int_to_real(const temp_int * a, temp_real * b){	b->a = a->a;	b->b = a->b;	if (b->a || b->b)		b->exponent = 16383 + 63 + (a->sign? 0x8000:0);	else {		b->exponent = 0;		return;	}	while (b->b >= 0) {		b->exponent--;		__asm__("addl %0,%0 ; adcl %1,%1"			:"=r" (b->a),"=r" (b->b)			:"0" (b->a),"1" (b->b));	}}

⌨️ 快捷键说明

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