Introducción
"¿Dónde guardar el dinero?" este es el título en broma de una publicación que aparece periódicamente en foros informáticos. Esto se refiere a la pregunta: en qué tipo de variables deben almacenarse los resultados de los cálculos de los cálculos financieros y económicos. Por lo general, esta pregunta surge entre los programadores que primero se enfrentan a tales cálculos. Entienden intuitivamente que el redondeo es indeseable o inaceptable aquí. Curiosamente, al mismo tiempo, a menudo recuerdan las leyendas sobre programadores astutos que lograron transferir la diferencia entre el valor exacto y redondeado de los cálculos financieros a su propia cuenta. Es cierto que estas historias se llamaron cuentos de hadas en el libro [1], escrito hace 50 años, e incluso allí solo se trataba de revisiones de sistemas bancarios, cuyos motivos (es decir, revisiones) podrían ser historias similares.
60 . . , - , , «» . «» , . , , «» , .
: 13% 1 30 . «» : 16.9 . «double», 1.68999999999999E-001 , 0.169 IEEE-754 . : ? – . ? , «» , «float» ?
, . «», , DECIMAL C#. [2], « Decimal , . Decimal . ». , , .
, , . , . – , . « » , .. , . DECIMAL C# « FLOAT», , . , .
IA-32 - . . , 64- , , Intel «» . 32- , . - , , , , , . , «» . - , – .
, , PL/1. , «» . , - IA-32 (, IA-16 1978 ) PL/1 . PL/1 [3], . , , 3-4% .
FIXED DECIMAL
PL/1 : FIXED, – FLOAT. , «FIXED/FLOAT» ( «/») . , , , «double».
PL/1 FIXED DECIMAL, , , FIXED DECIMAL(15,0) FIXED DECIMAL(12,4) .. . FIXED BINARY, , .
- BCD (Binary Coded Decimal). BCD . BCD . BCD , - , - . FIXED DECIMAL «» p ( 1 15) FLOOR((p+2)/2).
, 12345 5, PL/1 FLOOR((5+2)/2)=3 , 45 23 01. , 999 999 999 999 999. , , ,, 2013 $16,400,000,000,000, FIXED DECIMAL(14,0). , 60, PL/1 .
9 , 9 . , -2 (9-2)+1=8 1 98, 5 98 99 99.
, . – . , - .. , , « » . , 1.3 FIXED DECIMAL(2,1), 0.13 - FIXED DECIMAL(3,2), ( 0.169) FIXED DECIMAL(6,3), «», «» . «» 5, 6, PL/1 p1+p2+1, (a1a2-b1b2)+(a1b2+b1a2)i, .
- , , : , FLOOR/CEIL/TRUNC, .. FIXED DECIMAL . 8 99 ( ).
, . , .
;══════════════════ DECIMAL ═════════════════
PUBLIC ?DSUOP: ; PL/1
LEA ESI,[ESP]+4 ; 1 DECIMAL ( RET)
MOV ECX,8 ; DECIMAL
CLC ;
LEA EDI,[ESI+ECX] ; 2 DECIMAL
;---- ----
M2187:MOV AL,[EDI]
SBB AL,[ESI] ;
DAS
STOSB ;
INC ESI
LOOP M2187
POP ECX ;
MOV ESP,ESI ;
JMP ECX
;══════════════════ DECIMAL ══════════════════
EXTRN ?DOVER:NEAR
PUBLIC ?DADOP: ; PL/1
LEA ESI,[ESP]+4 ; 1 DECIMAL ( RET)
MOV ECX,8 ; DECIMAL
CLC ;
LEA EDI,[ESI+ECX] ; 2 DECIMAL
;---- DECIMAL ----
M2283:LODSB
ADC AL,[EDI] ;
DAA
STOSB ;
LOOP M2283
;---- ----
AND AL,0F0H ;
JZ @
CMP AL,90H ; ?
JNZ ?DOVER ;OVERFLOW DECIMAL
;---- ----
@: POP ECX ;
MOV ESP,ESI ;
JMP ECX
, - (ADC/SBB) (DAA/DAS), , 64- .
, , , , -, .
, FIXED DECIMAL: (, , ), PL/1 8 . , 15 31, 8 16, 16 31 . .
PL/1
, PL/1, , . FIXED DECIMAL FLOAT(53) – «double» .
test:proc main;
dcl x fixed decimal(6,3);
x=1.3;
x=x*0.13;
put skip data(x);
x=x/0.13;
put skip data(x);
dcl y float(53);
y=1.3;
y=y*0.13;
put skip data(y);
y=y/0.13;
put skip data(y);
end test;
.
FIXED DECIMAL , FLOAT - . , , , FIXED DECIMAL, , , « » .
, , PL/1, , , . , . , PL/1 E FLOAT, , . , , 25.0+1/3 , 1/3 (.. 15 ) «». 25.0+10/3 .
, , : . , , .
« », .. , , , PL/1 « 1». , . , [4] «» «». IA-32 , . 64- DAA/DAS , , , :
;--------------- DAA, X86-64 ------------------
PUBLIC DAA_X86_64:
PUSH RDX,RAX
LAHF
MOV EDX,EAX ;OLD CF OLD AL
AND AH,NOT 1B ; CF
;---- ----
TEST AH,10000B ; AF
JNZ @
PUSH RAX
AND AL,0FH
CMP AL,9 ; 9
POP RAX
JBE M2270
@: ADD AL,6 ;
OR AH,10000B ; AF
;---- ----
M2270:TEST DH,1B ; OLD CF
JNZ @
CMP DL,99H ;
JBE M2271
@: OR AH,1B ; CF
ADD AL,60H ;
;---- ----
M2271:SAHF
MOV [RSP],AL
POP RAX,RDX
RET
La base para cálculos precisos es la representación exacta de números en la memoria de la computadora. La representación BCD facilita la organización de cálculos precisos para números de cualquier longitud, es decir, cualquier precisión. Se ha demostrado en la práctica que para la mayoría de los cálculos económicos basta con una longitud de 15 decimales.
Literatura
1.D.R. Judd "Trabajar con archivos". Editorial "Mir" Moscú, 1975
2.http: //msdn.microsoft.com/ru-ru/library/system.decimal.aspx
3. D. Karavaev "Sobre la cuestión de mejorar el lenguaje de programación". Revista RSDN # 4 2011
4. L.F. Sternberg "Errores de programación y métodos de trabajo en el lenguaje PL / 1", Moscú "Ingeniería mecánica", 1993