程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> Vdsp(bf561)中的浮點運算(8):float除法運算

Vdsp(bf561)中的浮點運算(8):float除法運算

編輯:關於C++

1.1 Vdsp對float除法運算的處理

在vdsp下,可以很簡單地用:

float fdiv(float x, float y)
{
float r = x / y;
return r;
}

來完成浮點除法運算,編譯器自動將裡面的乘法操作轉換為___float32_div的函數調用,這個函數的調用實現在libdsp/fpdiv.asm中,在這個文件的開頭說明了這個函數的用法:

/******************************************************************************
Copyright(c) 2000-2008 Analog Devices Inc. IPDC BANGALORE, India.
All rights reserved
******************************************************************************
File Name      : fpdiv32.asm
Module Name    : floating point division
Label name     :  __float32_div
Description    : This function computes single precision signed floating point
division. Implemention is based on the algorithm mentioned in
the reference. Some more conditions are added in the present
algorithm to take care of various testcases.
Registers used:
Operands in  R0 & R1
R0- Numerator(X),R1- Denominator(Y)
R2 - R7 and P1

******************************************************************************
Special cases :
1) If(X == 0) Return   0.0 or -0.0  depending on sign of X,Y
2) If(Y == 0) Return   INF or -INF  depending on sign of X,Y
3) If(X == Y) Return   1.0 or -1.0  depending on sign of X,Y
4) If(Y == 1) Return   X or -X      depending on sign of X,Y
5) Underflow : If(EXP(X) - EXP(Y) < -149),return 0,
6) Overflow  : If((EXP(X) - EXP(Y) + 126) > 254), return NAN  or -NAN
depending on sign of X,Y

Reference  : Computer Architecture a Quantitative Approach
second edition
by John l Hennessy and David Patterson

!!NOTE- Uses non-standard clobber set in compiler:
DefaultClobMinusPABIMandLoop1Regs

Remember to change the #pragma regs_clobbered in fpdiv.c in softfloat if you
change this clobber set

********************************************************************************/

1.2 當x為nan或者inf

看代碼:

// First check if either operand is a NaN or inf, and handle certain
// identities with these values
R7 = (MAXBIASEXP+1) (Z);
CC = R6 == R7;
IF CC JUMP .HANDLE_NAN_INF_X;
……………
.HANDLE_NAN_INF_X:
// Return a NaN unless X is inf and Y is a valid number including 0, in
// which case return inf (signed appropriately)
CC = R5 < R7;  // if y is a valid number
R6 = R0 << 9;  // and if x is inf zero significand means X=inf
CC &= AZ;
IF CC JUMP .RET_INF (BP); // Return inf
// (predict branch to avoid 05-00-0428)

.RET_NAN:
R0 = -1;    // Otherwise return a NaN
(R7:4)=[SP++];  // Pop R7-R4 from stack
RTS;

l 當x為inf且y為一個合法的浮點數

返回inf

fdiv(inf, 0) = inf,CYCLE為48。

l 其它

返回nan

CYCLE為50。

1.3 當y為nan或者inf

看代碼:

CC = R5 == R7;
IF CC JUMP .HANDLE_NAN_INF_Y;
…………….
.HANDLE_NAN_INF_Y:
// Return NaN for all cases apart from 0/inf=0
CC = R0 == 0;  // x == 0
R7 = R1 << 9;  // and y == inf
CC &= AZ;
IF !CC JUMP .RET_NAN;
R0 = 0;
JUMP .SIGN_AND_RETURN;

.DIV_BY_ZERO:
// Return inf unless 0/0 in which case we return NaN.
CC = R0 == 0;
if CC JUMP .RET_NAN;
//else fallthrough - return inf

.RET_INF:
R0 = 0x7F8 (Z);  // Infinity.
R0 <<= 20;
……………….

下面是計算結果:

表達式 結果 CYCLE 0 / inf 0 50 0 / nan nan 52 inf / inf nan 50

1.4 當y為0

看代碼:

// Handle identities where neither operand is a NaN or inf
CC = R1 == 0;  // If X/0, return inf (or NaN if X=0)
IF CC JUMP .DIV_BY_ZERO;
……………
.DIV_BY_ZERO:
// Return inf unless 0/0 in which case we return NaN.
CC = R0 == 0;
if CC JUMP .RET_NAN;
//else fallthrough - return inf

.RET_INF:
R0 = 0x7F8 (Z); // Infinity.
R0 <<= 20;

.SIGN_AND_RETURN:
R0 = R0 | R3; // R3.31 contains the sign bit needed.
(R7:4)=[SP++];  // Pop R7-R4 from stack
RTS;

l 當x為零

0 / 0 = NAN

CYCLE = 52

l 當x不為零

任意合法浮點數 / 0 = inf

CYCLE = 46

1.5 當x為0

看代碼:

CC = R0 == 0; // IF 0/Y, return 0
IF CC JUMP .SIGN_AND_RETURN;
………
.SIGN_AND_RETURN:
R0 = R0 | R3; // R3.31 contains the sign bit needed.
(R7:4)=[SP++]; // Pop R7-R4 from stack
RTS;

直接返回0,所用的CYCLE為44。

1.6 當x == y

看代碼

CC = R0 == R1; // If X/X, return +/- 1.
IF CC R0 = R2;
IF CC JUMP .SIGN_AND_RETURN;
…….
.SIGN_AND_RETURN:
R0 = R0 | R3; // R3.31 contains the sign bit needed.
(R7:4)=[SP++]; // Pop R7-R4 from stack
RTS;

注意,這裡的等是除了符號位之外,其十六進制表示的值完全相等!

直接返回1或者-1,所用的CYCLE為48。

1.7 向上溢出

當一個大數除以一個小數,將發生向上溢出,這個時候的返回值是inf,而不是說明中的nan,想來應該是寫前面那段注釋時的失誤。

比如

1e30 / 1e-30 = inf

此時的CYCLE值為59。

1.8 正常計算

在正常計算一個浮點除法時,所用的CYCLE值為240,這是最慢的一個計算!

1.9 向下溢出

在代碼說明裡給出的下溢條件是

(EXP(X) - EXP(Y) + 126) > 254

此時返回0,所用的CYCYLE為243。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved