Binary coded decimal: Difference between revisions

Added Wren
(J)
(Added Wren)
Line 95:
(16b99 +bcd 1) -bcd 1
16b99</lang>
 
=={{header|Wren}}==
In Wren all numbers are represented by 64 bit floats and the language has no real concept of bytes, nibbles or even integers.
 
The following is therefore a simulation of BCD arithmetic using packed binary strings to represent decimal digits. It only works for non-negative integral numbers.
 
We can change to 'unpacked' notation simply by prepending '0000' to each 'digit' of the 'packed' notation.
 
In what follows, the hex prefix '0x' is simply a way of representing BCD literals and has nothing to do with hexadecimal as such.
<lang ecmascript>import "./check" for Check
import "./math" for Int
import "./str" for Str
import "./fmt" for Fmt
 
class BCD {
static init_() {
__bcd = [
"0000", "0001", "0010", "0011", "0100",
"0101", "0110", "0111", "1000", "1001"
]
__dec = {
"0000": "0", "0001": "1", "0010": "2", "0011": "3", "0100": "4",
"0101": "5", "0110": "6", "0111": "7", "1000": "8", "1001": "9"
}
}
 
construct new(n) {
if (n is String) {
if (n.startsWith("0x")) n = n[2..-1]
n = Num.fromString(n)
}
Check.nonNegInt("n", n)
if (!__bcd) BCD.init_()
_b = ""
for (digit in Int.digits(n)) _b = _b + __bcd[digit]
}
 
toInt {
var ns = ""
for (nibble in Str.chunks(_b, 4)) ns = ns + __dec[nibble]
return Num.fromString(ns)
}
 
+(other) {
if (!(other is BCD)) other = BCD.new(other)
return BCD.new(this.toInt + other.toInt)
}
 
-(other) {
if (!(other is BCD)) other = BCD.new(other)
return BCD.new(this.toInt - other.toInt)
}
 
toString {
var ret = _b.trimStart("0")
if (ret == "") ret = "0"
return ret
}
 
toUnpacked {
var ret = ""
for (nibble in Str.chunks(_b, 4)) ret = ret + "0000" + nibble
ret = ret.trimStart("0")
if (ret == "") ret = "0"
return ret
}
 
toHex { "0x" + this.toInt.toString }
}
 
var hexs = ["0x19", "0x30", "0x99"]
var ops = ["+", "-", "+"]
for (packed in [true, false]) {
for (i in 0...hexs.count) {
var op = ops[i]
var bcd = BCD.new(hexs[i])
var bcd2 = (op == "+") ? bcd + 1 : bcd - 1
var str = packed ? bcd.toString : bcd.toUnpacked
var str2 = packed ? bcd2.toString : bcd2.toUnpacked
var hex = bcd.toHex
var hex2 = bcd2.toHex
var un = packed ? "" : "un"
var w = packed ? 8 : 12
var args = [hex, op, hex2, un, w, str, op, str2]
Fmt.lprint("$s $s 1 = $-5s or, in $0spacked BCD, $*s $s 1 = $s", args)
}
if (packed) System.print()
}</lang>
 
{{out}}
<pre>
0x19 + 1 = 0x20 or, in packed BCD, 11001 + 1 = 100000
0x30 - 1 = 0x29 or, in packed BCD, 110000 - 1 = 101001
0x99 + 1 = 0x100 or, in packed BCD, 10011001 + 1 = 100000000
 
0x19 + 1 = 0x20 or, in unpacked BCD, 100001001 + 1 = 1000000000
0x30 - 1 = 0x29 or, in unpacked BCD, 1100000000 - 1 = 1000001001
0x99 + 1 = 0x100 or, in unpacked BCD, 100100001001 + 1 = 10000000000000000
</pre>
 
=={{header|Z80 Assembly}}==
9,476

edits