Binary coded decimal: Difference between revisions
→{{header|ALGOL 68}}: Use unsigned BCD, show addition/subtraction of larger numbers.
(Rust implementation) |
(→{{header|ALGOL 68}}: Use unsigned BCD, show addition/subtraction of larger numbers.) |
||
Line 83:
0100</pre>
=={{header|ALGOL 68}}==
<lang algol68>BEGIN # implements packed BCD arithmetic
INT x99 = ( 9 * 16 ) + 9;
# structure to hold BCD values #
MODE BCD = STRUCT( INT
, BOOL carry # TRUE if the value overflowed, #
); # FALSE otherwise #
# constructs a BCD value from a, assuming it is in the correct format #
# if the value has overflowed, it is truncated to a valid value and #
Line 109 ⟶ 110:
ELSE BCD( ( ( ( a OVER 10 ) MOD 10 ) * 16 ) + ( a MOD 10 ), a > x99 )
FI # TOBCD # ;
# returns a two-digit string representation of the BCD value a #
OP TOSTRING = ( BCD a )STRING: IF value OF a < 0 THEN "-" ELSE "" FI
Line 114 ⟶ 120:
+ whole( ABS value OF a MOD 16, 0 )
;
# returns a string representation of the row of BCD values in a #
# assumes the most significant digits are in a[ LWB a ] #
OP TOSTRING = ( []BCD a )STRING:
STRING result := "";
FOR b pos FROM LWB a TO UPB a DO result +:= TOSTRING a[ b pos ] OD;
result
END # TOSTRING # ;
# returns the sum of a and b, a and b can be positive or negative #
# the result is always positive, if it would be negative, it is #
OP + = ( BCD a, b )BCD:
BEGIN
INT
BOOL ap =
INT a2 = av
INT bcd value =
IF
THEN # both positive or both negative
IF ap THEN result ELSE - result FI
ELIF
THEN
ELSE
IF ap THEN - result ELSE - result FI
IF bcd value >= 0 THEN # result is positive #
ASBCD bcd value
ELSE # result is negative - tens complement #
BCD result := ( bcd 99 + ASBCD bcd value ) + bcd 1;
carry OF result := TRUE;
result
FI
END # + # ;
# returns the value of b negated, carry is preserved #
OP - = ( BCD a )BCD: BCD( - value OF a, carry OF a );
# returns the difference of a and b, a and b can be positive or negative #
OP - = ( BCD a, b )BCD: a + - b;
# adds b to a and resurns a #
OP +:= = ( REF BCD a, BCD b )REF BCD: a := a + b;
# subtracts b from a and resurns a #
OP -:= = ( REF BCD a, BCD b )REF BCD: a := a - b;
# task test cases #
BCD r;▼
▲ r := TOBCD( 30 ) - TOBCD( 1 );
▲ print( ( TOSTRING r, newline ) );
▲ r := TOBCD( 99 ) + TOBCD( 1 );
print( ( IF carry OF r THEN "1" ELSE "" FI, TOSTRING r, newline ) );
print( ( newline ) );
▲ # additional test cases #
# use the 2-digit BCD to add/subtract larger numbers #
[ 1 : 6 ]BCD
( TOBCD 1,
[]BCD a12 =
print( ( TOSTRING ( TOBCD( v ) + TOBCD( i ) ), " " ) )▼
( TOBCD 1, TOBCD 11, TOBCD 11, TOBCD 11, TOBCD 11, TOBCD 11 );
▲ OD;
TO 10 DO # repeatedly add s12 to d12 #
▲ print( ( newline ) )
print(
FOR b pos FROM UPB d12 BY -1 TO LWB d12 DO
▲ BEGIN
d12[
BOOL need carry =
IF
carry
print( ( TOSTRING d12, newline ) )
TO 10 DO # repeatedly subtract a12 from d12 #
FOR b pos FROM UPB d12 BY -1 TO LWB d12 DO
d12[ b pos ] -:= a12[ b pos ];
BOOL need carry = carry OF d12[ b pos ];
IF carry THEN d12[ b pos ] -:= bcd 1 FI;
carry := need carry OR carry OF d12[ b pos ]
print( ( TOSTRING d12, newline ) )
OD
END</lang>
{{out}}
Line 176 ⟶ 211:
100
012345678901 + 011111111111 = 023456790012
023456790012 + 011111111111 = 034567901123
034567901123 + 011111111111 = 045679012234
045679012234 + 011111111111 = 056790123345
056790123345 + 011111111111 = 067901234456
067901234456 + 011111111111 = 079012345567
079012345567 + 011111111111 = 090123456678
090123456678 + 011111111111 = 101234567789
101234567789 + 011111111111 = 112345678900
112345678900 + 011111111111 = 123456790011
123456790011 - 011111111111 = 112345678900
112345678900 - 011111111111 = 101234567789
101234567789 - 011111111111 = 090123456678
090123456678 - 011111111111 = 079012345567
079012345567 - 011111111111 = 067901234456
067901234456 - 011111111111 = 056790123345
056790123345 - 011111111111 = 045679012234
045679012234 - 011111111111 = 034567901123
034567901123 - 011111111111 = 023456790012
023456790012 - 011111111111 = 012345678901
</pre>
|