2011-09-27 173 views
7

我對cobol中計算函數的圓角感到困惑。計算圓角在cobol中

聲明:

VAR-A  PIC S9(9)V99 COMP-3. 
VAR-B  PIC S9(9)V9(6) COMP-3. 

程序。

MOVE +12.08 TO VAR-A. 
MOVE +6.181657 TO VAR-B. 


COMPUTE VAR-A ROUNDED = VAR-A + VAR-B. 

VAR-A的結果是18.27還是18.26? cobol在計算上會做什麼? 它會將VAR-B首先循環到VAR-A中指定的小數位,還是將cobol添加2個變量,然後將它們四捨五入到VAR-A中指定的小數位?

任何幫助將不勝感激。

@NealB,

這樣如何例如:

聲明:

01 VAR-ARRAY OCCURS 22 TIMES. 
    03 VAR-A  PIC S9(9)V9(6) COMP-3. 


01 VAR-B  PIC S9(9)V99 COMP-3. 

假定VAR-A是一個數組,並且,以下是其值:

VAR-A(01) = 123.164612 
VAR-A(02) = 12.07865 
VAR-A(03) = 6.181657 
VAR-A(04) = 1.744353 
VAR-A(05) = 6.118182 
VAR-A(06) = 1.744353 
VAR-A(07) = 6.158715 
VAR-A(08) = 1.744353 
VAR-A(09) = 6.194759 
VAR-A(10) = 1.744353 
VAR-A(11) = 3.037896 
VAR-A(12) = 1.743852 
VAR-A(13) = 6.14653 
VAR-A(14) = 1.744353 
VAR-A(15) = 0.000377 
VAR-A(16) = 1.743852 
VAR-A(17) = 6.144363 
VAR-A(18) = 1.743852 
VAR-A(19) = 0.007649 
VAR-A(20) = 1.744353 
VAR-A(21) = 0.000377 
VAR-A(22) = 1.744353 

VAR-B的價值是:

VAR-B = 405.25 

程序:

PERFORM VAR-IDX FROM 1 BY 1 UNTIL VAR-IDX > 22 
    COMPUTE VAR-B ROUNDED = VAR-B + VAR-A(VAR-IDX) 
END-PERFORM. 

爲什麼我得到597.87的VAR-B作爲計算後的結果?

+0

奇怪的答案......我得到597.88 ,我相信這是正確的。你正在使用哪種COBOL編譯器? – NealB

回答

5

我相信默認的COBOL舍入行爲是:離零最近。

COMPUTE VAR-A ROUNDED = VAR-A + VAR-B 

應導致VAR-A含有18.26

表達已被評估之後發生舍入。更有趣的例子可能是:

01 VAR-A  PIC S9(9)V99 COMP-3.    
01 VAR-B  PIC S9(9)V9(6) COMP-3.    
01 VAR-C  PIC S9(9)V9(6) COMP-3.    

MOVE +12.08 TO VAR-A.       
MOVE +06.182000 TO VAR-B.      
MOVE +00.004000 TO VAR-C.      
COMPUTE VAR-A ROUNDED = VAR-A + VAR-B + VAR-C. 

結果是18.27。將VAR-BVAR-C四捨五入到小數點後2位,因爲VAR-B輪次爲6.18,VAR-C輪次爲0.00。其結果實際上是18.27,因此在對錶達式進行評估之後進行四捨五入。

回覆編輯的問題

不漂亮的輸出,但是這是我的計算如何去使用IBM的企業COBOL z/OS的

 
VAR-IDX = 01 VAR-B = +405.25 VAR-A = +123.164612 VAR-B + VAR-A = +528.41 
VAR-IDX = 02 VAR-B = +528.41 VAR-A = +012.078650 VAR-B + VAR-A = +540.49 
VAR-IDX = 03 VAR-B = +540.49 VAR-A = +006.181657 VAR-B + VAR-A = +546.67 
VAR-IDX = 04 VAR-B = +546.67 VAR-A = +001.744353 VAR-B + VAR-A = +548.41 
VAR-IDX = 05 VAR-B = +548.41 VAR-A = +006.118182 VAR-B + VAR-A = +554.53 
VAR-IDX = 06 VAR-B = +554.53 VAR-A = +001.744353 VAR-B + VAR-A = +556.27 
VAR-IDX = 07 VAR-B = +556.27 VAR-A = +006.158715 VAR-B + VAR-A = +562.43 
VAR-IDX = 08 VAR-B = +562.43 VAR-A = +001.744353 VAR-B + VAR-A = +564.17 
VAR-IDX = 09 VAR-B = +564.17 VAR-A = +006.194759 VAR-B + VAR-A = +570.36 
VAR-IDX = 10 VAR-B = +570.36 VAR-A = +001.744353 VAR-B + VAR-A = +572.10 
VAR-IDX = 11 VAR-B = +572.10 VAR-A = +003.037896 VAR-B + VAR-A = +575.14 
VAR-IDX = 12 VAR-B = +575.14 VAR-A = +001.743852 VAR-B + VAR-A = +576.88 
VAR-IDX = 13 VAR-B = +576.88 VAR-A = +006.146530 VAR-B + VAR-A = +583.03 
VAR-IDX = 14 VAR-B = +583.03 VAR-A = +001.744353 VAR-B + VAR-A = +584.77 
VAR-IDX = 15 VAR-B = +584.77 VAR-A = +000.000377 VAR-B + VAR-A = +584.77 
VAR-IDX = 16 VAR-B = +584.77 VAR-A = +001.743852 VAR-B + VAR-A = +586.51 
VAR-IDX = 17 VAR-B = +586.51 VAR-A = +006.144363 VAR-B + VAR-A = +592.65 
VAR-IDX = 18 VAR-B = +592.65 VAR-A = +001.743852 VAR-B + VAR-A = +594.39 
VAR-IDX = 19 VAR-B = +594.39 VAR-A = +000.007649 VAR-B + VAR-A = +594.40 
VAR-IDX = 20 VAR-B = +594.40 VAR-A = +001.744353 VAR-B + VAR-A = +596.14 
VAR-IDX = 21 VAR-B = +596.14 VAR-A = +000.000377 VAR-B + VAR-A = +596.14 
VAR-IDX = 22 VAR-B = +596.14 VAR-A = +001.744353 VAR-B + VAR-A = +597.88 
FINAL RESULT = +597.88            
1

它取決於中間舍入和最終舍入集。

看到此的更多信息:

D.13a舍入

COBOL提供指定在算術語句和在評估過程的各個點表達式四捨五入的能力而當數值在接收存儲製備數據項。

有八種不同形式的本標準四捨五入支持:

•外之ZERO:舍入是較大幅度的最接近的值。

•最近從零開始:舍入爲最接近的值。如果兩個值相等,則選擇幅值較大的值。這種模式歷來與標準COBOL以前版本中的ROUNDED子句相關聯。

•最近 - 偶數:舍入是最接近的值。如果兩個值相等,則選擇最右邊數字爲偶數的值。這種模式有時被稱爲「銀行家舍入」。

•NEAREST-TOWARD-ZERO:舍入爲最接近的值。如果兩個值相等,則選擇較小幅度的值。

•PROHIBITED:由於該值不能被精確地在所需的格式表示的,EC-SIZE截斷條件設置爲存在,並且操作的結果是不確定的。

•TOWARD-GREATER:四捨五入的值是代數值較大的最近值。

•TOWARD-LESSER:TOWARD-LESSER:四捨五入朝向代數值較小的最近值。

•切分:舍入是最接近其值較小的值。歷史上這種模式與ROUNDED子句的缺失以及之前COBOL標準中形成的中間結果有關。

程序員可以指定在通過ROUNDED子句存儲到接收數​​據項中時各個中間值的舍入方式;當ROUNDED子句通過IDENTIFICATION DIVISION的OPTIONS段落的DEFAULT ROUNDED MODE子句在接收數據項上沒有進一步限定時,可以選擇舍入的默認模式;並可指定如何通過中間循環子句對中間格式的算術運算和轉換進行四捨五入。

D.13a.1中間舍入

中間舍入適用於當包含在算術運算或算術表達式被檢索的數據項,和算術運算符的執行過程中,以產生中間結果。

在以前的標準,對於乘法和除法的標準算術舍入爲不精確結果的缺省模式是截斷到32個顯著數字。此標準中的默認值不變,也是標準二進制和標準十進制算術的默認值。

當中間值可以恰當地以適當的中間格式表示時,使用確切的值。

如果無法精確表示值,用戶現在也可以指定其他方式的舍入算術運算和通過OPTIONS的可選中間圓角子句在算術運算中使用的中間形式的轉換和轉換鑑定部門的一段。

具體來說,有以下選項:

•中間舍入最接近外之-ZERO •中間舍入最接近,甚至 •中間舍入禁止 •中間舍入截斷

其中的子條款說明在D.13a,Rounding中找到。

如果未指定中間舍入子句,中間舍入IS截斷推測。這與以前的標準沒有什麼不同。

D.13a.2最終四捨五入(圓形子句)

最終的舍入應用於表達式或語句的最終結果的形成,在語句或表達式的求值完成,之前的結果放在目的地。這種舍入形式與ROUNDED子句相關。在以前的COBOL標準中,只提供了兩種「最終」舍入方法:舍入較小的數量(截斷,由缺少ROUNDED子句表示);並四捨五入到最接近的值,如果兩個值相等,則選擇具有較大幅度的值(通過ROUNDED子句的存在來表示)。

圓形的條款已得到增強,允許任何四捨五入的八種模式(包括兩個以前可用)明確的選擇:

•ROUNDED模式是遠離式-ZERO •ROUNDED模式最接近-AWAY - 從-ZERO •ROUNDED模式是最近的偶數 •ROUNDED模式最接近的趨向零 •ROUNDED模式被禁止 •圓角模式向-GREATER •ROUNDED模式向-LESSER •ROUNDED模式是TRUNCATION

如果ROUNDED子句對於給定結果不存在,則應用ROUNDED MODE IS TRUNCATION的規則。

提供IDENTIFICATION DIVISION的OPTIONS段落中的可選DEFAULT ROUNDED MODE子句,以允許用戶指定ROUNDED子句出現的任何操作的舍入模式,而無需MODE子條款。
的DEFAULT四捨五入MODE子句可以採取任何的這些形式:

•DEFAULT ROUNDED模式外之ZERO IS•DEFAULT四捨五入模式最接近外之-ZERO •DEFAULT四捨五入模式是最近的偶數 •DEFAULT四捨五入模式最接近的趨向零 •DEFAULT四捨五入模式是禁止 •DEFAULT四捨五入模式向-GREATER •DEFAULT四捨五入模式向-LESSER •DEFAULT四捨五入模式被截斷

爲其缺省圓角模式的子句是子句a在D.13a,舍入中再次描述。

如果程序中沒有出現DEFAULT ROUNDED MODE子句,那麼沒有MODE IS子句的ROUNDED子句的效果就好像已經指定了ROUNDED MODE是從最近的ZERO開始。這提供了以前的COBOL標準中可用的相同功能。

如果出現DEFAULT ROUNDED MODE子句,則沒有MODE IS子句的ROUNDED子句視爲它們已使用DEFAULT ROUNDED MODE子句中指定的舍入模式指定。

+0

感謝Patrick的超級快速回復。糾正我,如果我錯了,我上面提到的樣本正在使用最後的四捨五入。由於我沒有指定默認圓形模式,舍入模式是圓形模式是從零開始。 cobol做的是在添加變量並將其放到目標變量之前對其進行四捨五入。這也意味着VAR-A的價值將是+18.26? – Grekoz

+0

以上看起來像是從COBOL的下一個標準草案中解脫出來的。我不認爲許多商業COBOL編譯器完全支持這一點。在此之前,我相信大多數人採用的默認舍入模式是:距離零最近的距離。 – NealB

+0

是的NealB是正確的。 –

-1
IDENTIFICATION DIVISION. 
PROGRAM-ID. HELLO. 
DATA DIVISION. 
WORKING-STORAGE SECTION. 

01 VAR_NUM PIC 9(3)V9(02). 
01 VAR_RESULT PIC 9(3). 


PROCEDURE DIVISION. 
    MOVE 256.50 TO VAR_NUM. 
    COMPUTE VAR_NUM ROUNDED = VAR_NUM/100. 
    MULTIPLY 100 BY VAR_NUM 
    MOVE VAR_NUM TO VAR_RESULT. 
    DISPLAY "Result : " VAR_RESULT. 

STOP RUN. 
+0

這個答案與這個問題無關,你已經將它作爲另一個答案也發佈了。該代碼是無用的。如果任何一個問題想要這樣做,答案將是「計算VAR-RESULT ROUNDED = VAR-NUM」。沒有'DIVIDE',沒有'MULTIPLY'和'MOVE'。請考慮刪除你的這些答案。 –