Binary coded decimal: Difference between revisions

m
Automated syntax highlighting fixup (second round - minor fixes)
m (syntax highlighting fixup automation)
m (Automated syntax highlighting fixup (second round - minor fixes))
Line 18:
The 6502 is a bit different in that it has a special operating mode where all addition and subtraction is handled as binary-coded decimal. Like the 68000, this must be invoked ahead of time, rather than using the Intel method of doing the math normally and then correcting it after the fact. (This special operating mode won't work on the aforementioned Ricoh 2A03, which performs math in "normal" mode even if the decimal flag is set.)
 
<syntaxhighlight lang="6502asm">sed ;set decimal flag; now all math is BCD
lda #$19
clc
Line 53:
=={{header|68000 Assembly}}==
The 68000 has special mathematics commands for binary-coded decimal. However, they only work at byte length, and cannot use immediate operands. Even adding by 1 this way requires you to load 1 into a register first.
<syntaxhighlight lang="68000devpac"> MOVEQ #$19,D0
MOVEQ #1,D1
MOVEQ #0,D2
Line 84:
=={{header|ALGOL 68}}==
Algol 68 does not have BCD as standard. This sample implements 2-digit unsigned packed decimal numbers, similar to the [[#PL/M|PL/M]] sample. The 2-digit numbers are then used to provide addition/subtraction of larger numbers.
<syntaxhighlight lang="algol68">BEGIN # implements packed BCD arithmetic #
INT x99 = ( 9 * 16 ) + 9; # maximum unsigned 2-digit BCD value #
# structure to hold BCD values #
Line 232:
023456790012 - 011111111111 = 012345678901
</pre>
 
=={{header|ALGOL W}}==
{{Trans|ALGOL 68}}
<syntaxhighlight lang="pascal">begin % implements packed BCD arithmetic %
integer X99; % maximum unsigned 2-digit BCD value %
% structure to hold BCD values %
Line 398 ⟶ 397:
023456790012 - 011111111111 = 012345678901
</pre>
 
=={{header|Forth}}==
This code implements direct BCD arithmetic using notes from Douglas Jones from the University of Iowa: https://homepage.cs.uiowa.edu/~jones/bcd/bcd.html#packed
<syntaxhighlight lang=Forth"forth">
\ add two 15 digit bcd numbers
\
Line 430 ⟶ 428:
99 1 bcd+ . 100 ok
</pre>
 
=={{header|J}}==
 
Here, we represent hexadecimal numbers using J's constant notation, and to demonstrate bcd we generate results in that representation:
 
<syntaxhighlight lang=J"j"> bcd=: &.((10 #. 16 #.inv ". ::]) :. ('16b',16 hfd@#. 10 #.inv ]))
16b19 +bcd 1
16b20
Line 449 ⟶ 446:
For reference, here are decimal and binary representations of the above numbers:
 
<syntaxhighlight lang=J"j"> (":,_16{.' '-.~'2b',":@#:) 16b19
25 2b11001
(":,_16{.' '-.~'2b',":@#:) 16b20
Line 464 ⟶ 461:
25
NB. ...</syntaxhighlight>
 
=={{header|Julia}}==
Handles negative and floating point numbers (but avoid BigFloats due to very long decimal places from binary to decimal conversion).
<syntaxhighlight lang="ruby">const nibs = [0b0, 0b1, 0b10, 0b11, 0b100, 0b101, 0b110, 0b111, 0b1000, 0b1001]
 
"""
Line 577 ⟶ 573:
BCD 99 (UInt8[0x99]) + BCD 1 ((UInt8[0x01], 1)[1]) = BCD 100 ((UInt8[0x01, 0x00], 1))
</pre>
 
=={{header|Pascal}}==
==={{header|Free Pascal}}===
There exist a special unit for BCD, even with fractions.Obvious for Delphi compatibility.
<syntaxhighlight lang="pascal">program CheckBCD;
// See https://wiki.freepascal.org/BcdUnit
{$IFDEF FPC} {$MODE objFPC}{$ELSE} {$APPTYPE CONSOLE} {$ENDIF}
Line 618 ⟶ 613:
99*99 =9801
</pre>
 
=={{header|Phix}}==
=== using fbld and fbstp ===
The FPU maths is all as normal (decimal), it is only the load and store that convert from/to BCD.<br>
While I supply everything in decimal, you could easily return and pass around the likes of acc and res.
<!--<syntaxhighlight lang=Phix"phix">-->
<span style="color: #008080;">without</span> <span style="color: #008080;">javascript_semantics</span> <span style="color: #000080;font-style:italic;">-- (not a chance!)</span>
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1.0.2"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- #ilASM{fbld, fbstp} added</span>
Line 678 ⟶ 672:
The aaa, aas, aam, and aad instructions are also available.
Same output as above, of course
<!--<syntaxhighlight lang=Phix"phix">-->
<span style="color: #008080;">without</span> <span style="color: #008080;">javascript_semantics</span> <span style="color: #000080;font-style:italic;">-- (not a chance!)</span>
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1.0.2"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- #ilASM{aaa, etc} added</span>
Line 710 ⟶ 704:
With routines to convert between decimal and bcd, same output as above, of course.
No attempt has been made to support fractions or negative numbers...
<!--<syntaxhighlight lang=Phix"phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> <span style="color: #000080;font-style:italic;">-- (no requires() needed here)</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">bcd_decode</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">bcd</span><span style="color: #0000FF;">)</span>
Line 767 ⟶ 761:
<span style="color: #000000;">test3</span><span style="color: #0000FF;">(</span><span style="color: #000000;">99</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'+'</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
 
=={{header|PL/M}}==
{{works with|8080 PL/M Compiler}} ... under CP/M (or an emulator)
The 8080 PL/M compiler supports packed BCD by wrapping the 8080/Z80 DAA instruction with the DEC built in function, demonstrated here. Unfortunately, I couldn't get the first use of DEC to yeild the correct result without first doing a shift operation. Not sure if this is a bug in the program, the compiler or the 8080 emulator or that I'm misunderstanding something...
This is basically {{Trans|Z80 Assembly}}
<syntaxhighlight lang="pli">100H: /* DEMONSTRATE PL/M'S BCD HANDLING */
 
BDOS: PROCEDURE( FN, ARG ); /* CP/M BDOS SYSTEM CALL */
Line 813 ⟶ 806:
 
A more complex example, showing how the DEC function can be used to perform unsigned BCD addition and subtraction on arbitrary length BCD numbers.
<syntaxhighlight lang="pli">100H: /* DEMONSTRATE PL/M'S BCD HANDLING */
 
BDOS: PROCEDURE( FN, ARG ); /* CP/M BDOS SYSTEM CALL */
Line 912 ⟶ 905:
023456790012 - 011111111111 = 012345678901
</pre>
 
=={{header|Rust}}==
Based on the Forth implementation re: how to implement BCD arithmetic in software. Uses operator overloading for new BCD type.
<syntaxhighlight lang=Rust"rust">
#[derive(Copy, Clone)]
pub struct Bcd64 {
Line 970 ⟶ 962:
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
</pre>
 
=={{header|Wren}}==
{{libheader|Wren-check}}
Line 983 ⟶ 974:
 
In what follows, the hex prefix '0x' is simply a way of representing BCD literals and has nothing to do with hexadecimal as such.
<syntaxhighlight lang="ecmascript">import "./check" for Check
import "./math" for Int
import "./str" for Str
Line 1,073 ⟶ 1,064:
0x99 + 1 = 0x100 or, in unpacked BCD, 100100001001 + 1 = 10000000000000000
</pre>
 
=={{header|Z80 Assembly}}==
The <code>DAA</code> function will convert an 8-bit hexadecimal value to BCD after an addition or subtraction is performed. The algorithm used is actually quite complex, but the Z80's dedicated hardware for it makes it all happen in 4 clock cycles, tied with the fastest instructions the CPU can perform.
 
<syntaxhighlight lang="z80">
PrintChar equ &BB5A ;Amstrad CPC kernel's print routine
org &1000
10,327

edits