Binary coded decimal: Difference between revisions

→‎{{header|ALGOL W}}: Use unsigned BCD and added addition/subtraction of larger numbers
(→‎{{header|ALGOL 68}}: Use unsigned BCD, show addition/subtraction of larger numbers.)
(→‎{{header|ALGOL W}}: Use unsigned BCD and added addition/subtraction of larger numbers)
Line 235:
=={{header|ALGOL W}}==
{{Trans|ALGOL 68}}
<lang algolwpascal>begin % implements packed BCD arithmetic for 2-digit signed packed BCD %
integer X99; % maximum unsigned 2-digit BCD value %
% structure to hold BCD values %
record BCD ( integer dValue % signed BCD value: -x99 to x99 %
; logical dCarry % TRUE if the value overflowed, %
); % FALSE otherwise %
reference(BCD) bcd99, bcd1, bcd0;
% 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 273 ⟶ 274:
% writes a BCD value with a preceeding newline %
procedure writeBcd ( reference(BCD) value a ) ; begin write(); writeOnBcd( a ) end;
% writes an array of BCD values - the bounds should be 1 :: ub %
procedure showBcd ( reference(BCD) array a ( * ); integer value ub ) ;
for i := 1 until ub do writeOnBcd( a( i ) );
 
% returns the sum of a and b, a and b can be positive or negative %
Line 297 ⟶ 301:
if ap then bcdResult := - bcdResult
end if_ap_eq_bp__av_ge_bv__;
asBcd(if bcdResult )>= 0 then begin % result is positive %
asBcd( bcdResult )
end
else begin % negative result - tens complement %
reference(BCD) sum;
sum := addBcd( addBcd( bcd99, asBcd( bcdResult ) ), bcd1 );
dCarry(sum) := true;
sum
end if_bcdResult_ge_0__
end addBcd;
% returns the difference of a and b, a and b can be positive or negative %
reference(BCD) procedure subtractBcd ( reference(BCD) value a, b ) ; addBcd( a, negateBcd( b ) );
 
X99 := ( 9 * 16 ) + 9;
bcd99 := toBcd( 99 );
bcd1 := toBcd( 1 );
bcd0 := toBcd( 0 );
 
begin % task test cases %
Line 311 ⟶ 326:
if dCarry(r) then write( s_w := 0, "1" );
writeOnBcd( r );
end;
 
begin % use the 2-digit BCD to add/subtract larger numbers %
reference(BCD) array d12, a12 ( 1 :: 6 );
integer dPos;
write();
dPos := 0;
for v := 1, 23, 45, 67, 89, 01 do begin
dPos := dPos + 1;
d12( dPos ) := toBcd( v )
end for_v ;
dPos := 0;
for v := 1, 11, 11, 11, 11, 11 do begin
dPos := dPos + 1;
a12( dPos ) := toBcd( v )
end for_v ;
for i := 1 until 10 do begin % repeatedly add a12 to d12 %
logical carry;
write();showBcd( d12, 6 );writeon( " + " );showBcd( a12, 6 );writeon( " = " );
carry := false;
for bPos := 6 step -1 until 1 do begin
logical needCarry;
d12( bPos ) := addBcd( d12( bPos ), a12( bPos ) );
needCarry := dCarry(d12( bPos ));
if carry then d12( bPos ) := addBcd( d12( bPOs ), bcd1 );
carry := needCarry or dCarry(d12( bPos ))
end for_bPos ;
showBcd( d12, 6 )
end for_i;
for i := 1 until 10 do begin % repeatedly subtract a12 from d12 %
logical carry;
write();showBcd( d12, 6 );writeon( " - " );showBcd( a12, 6 );writeon( " = " );
carry := false;
for bPos := 6 step -1 until 1 do begin
logical needCarry;
d12( bPos ) := subtractBcd( d12( bPos ), a12( bPos ) );
needCarry := dCarry(d12( bPos ));
if carry then d12( bPos ) := subtractBcd( d12( bPOs ), bcd1 );
carry := needCarry or dCarry(d12( bPos ))
end for_bPos ;
showBcd( d12, 6 )
end for_i;
end
 
end.</lang>
{{out}}
Line 318 ⟶ 376:
29
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>
 
3,028

edits