FPREM1 - 部分餘數

操作碼

指令

說明

D9 F5

FPREM1

將 ST(0) 替換成 ST(0) 除以 ST(1) 的 IEEE 餘數。

說明

計算將 ST(0) 暫存器中的值(被除數)除以 ST(1) 暫存器中的值(除數或)得到的 IEEE 餘數,結果儲存到 ST(0)。餘數表示以下值:

Remainder ST(0) - (Q * ST(1))

這裡,Q 是一個整數值,通過將 [ST(0) / ST(1)] 的實數商向最接近的整數值取整得到。除非計算部分餘數(如下所述),否則餘數的值比模的一半小。

此指令會產生精確的結果;不會產生精度(不精確)異常,且不受取整控制的影響。下表顯示計算各類數值的餘數時得到的結果(假設未發生下溢)。

 

ST(1)

 

 

 

 

 

ST(0)

 

-

-F

-0

+0

+F

+

NaN

-

*

*

*

*

*

*

NaN

-F

ST(0)

±F 或 -0

**

**

±F 或 -0

ST(0)

NaN

-0

-0

-0

*

*

-0

-0

NaN

+0

+0

+0

*

*

+0

+0

NaN

+F

ST(0)

±F 或 +0

**

**

±F 或 +0

ST(0)

NaN

+

*

*

*

*

*

*

NaN

NaN

NaN

NaN

NaN

NaN

NaN

NaN

NaN

備註:F 表示有限實數。

* 表示浮點算術運算元無效 (#IA) 異常。

** 表示浮點除零 (#Z) 異常。

結果為 0 時,其符號與被除數的相同。模為 時,結果與 ST(0) 中的值相同。

FPREM1 指令計算 IEEE 754 標準規定的餘數。此指令執行的操作與 FPREM 指令的不同,表現在它將 ST(0) 除以 ST(1) 的商向整數取整(請參閱下文的“操作”部分)。

同 FPREM 指令一樣,FPREM1 通過反覆執行減法來計算餘數,但是在指令的一次執行中,只能將 ST(0) 的指數減少不超過 63。如果指令成功產生小於模的一半的餘數,則操作完成,並清除 FPU 狀態字中的 C2 標誌。否則將設定 C2,此時 ST(0) 中的結果稱為部分餘數。部分餘數的指數將比原始被除數的指數至少小 32。軟體可以重複執行指令(將 ST(0) 中的部分餘數用作被除數),直到清除 C2。(請注意,執行這樣的餘數計算循環時,在循環的指令之間,需要 FPU 且優先順序更高的中斷例程可能會強制進行上下文切換)。

FPREM1 指令的重要用途之一是減少周期函數的參數。減法完成時,指令將商的三個最低有效位儲存到 FPU 狀態字的 C3、C1 及 C0 標誌。由於減少正切函式的參數(使用模 /4)時,會將原始角度定位到單位圓的八個扇區之一,所以此資訊非常重要。

操作

D exponent(ST(0)) - exponent(ST(1));
IF D < 64
THEN
Q Integer(RoundTowardNearestInteger(ST(0) / ST(1)));
ST(0) ST(0) - (ST(1) * Q);
C2 0;
C0, C3, C1 LeastSignificantBits(Q); (* Q2, Q1, Q0 *)
ELSE
C2 1;
N an implementation-dependent number between 32 and 63;
QQ Integer(TruncateTowardZero((ST(0)/ST(1)) 2(D-N) ST(0) ST(0) - (ST(1) * QQ * 2(D - N)

影響的 FPU 標誌

C0 - 設定為商的位 2 (Q2)。

C1 - 如果發生堆疊下溢,則設定為 0;否則設定為商的最低有效位 (Q0)。

C2 - 如果減法完成,則設定為 0;如果未完成,則設定為 1。

C3 - 設定為商的位 1 (Q1)。

浮點異常

#IS - 發生堆疊下溢。

#IA - 源運算元是 SNaN 值、模(除數)是 0、被除數是 ,或是不支援的格式。

#D - 源運算元是非規格化值。

#U - 結果對於目標格式而言太小。

保護模式異常

#NM - 如果 CR0 中的 EM 或 TS 設定為 1。

實地址模式異常

#NM - 如果 CR0 中的 EM 或 TS 設定為 1。

虛 8086 模式異常

#NM - 如果 CR0 中的 EM 或 TS 設定為 1。