Skip to content

Commit

Permalink
Merge pull request #22 from olyutorskii/release/v2.101.2
Browse files Browse the repository at this point in the history
Release/v2.101.2
  • Loading branch information
olyutorskii committed Apr 24, 2017
2 parents 2f157f4 + e386434 commit 4e4e08a
Show file tree
Hide file tree
Showing 19 changed files with 1,356 additions and 1,173 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ DoubDabC Changelog
## WIP
Released on 20XX-XX-XX

## v2.101.2
Released on 2017-04-24
- Merge DecimalText and DecimalOut to BcdSequence
- Extended Writer class removed. See JarabraDix new project.
- Split BcdUtils class from BcdRegister
- Add BcdArrays

## v1.103.2
Released on 2017-03-22
- Add DecimalWriter which supports print(int) #16
Expand Down
15 changes: 5 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# DoubDabC #

[![Build Status](https://travis-ci.org/olyutorskii/DoubDabC.svg?branch=master)]
(https://travis-ci.org/olyutorskii/DoubDabC)
[![Build Status](https://travis-ci.org/olyutorskii/DoubDabC.svg?branch=master)](https://travis-ci.org/olyutorskii/DoubDabC)

-----------------------------------------------------------------------

## What is DoubDabC ? ##

* **DoubDabC** is a Java library
that supports **binary integer value to decimal sequence conversion**.
that supports **binary integer value to decimal sequence conversion**
with alternative algorithm.

* Yes, it will substitute implementations such as
`Integer.toString(int)`, `System.out(=PrintStream).println(int)` and so on.
`Integer.toString(int)` and so on.


## DoubDabC implementation ##
Expand Down Expand Up @@ -47,15 +47,10 @@ as Arabic numeral characters\(0-9\) sequence output.

* `CharSequence` wrapper class is provided.

* Extended `Writer` class is provided
which supports `print(int)` & `print(long)` methods
like `PrintWriter`.


## Limitations ##

* DoubDabC does not support negative values
with the exception of `DecimalWriter`.
* DoubDabC does not support negative values.
Signed-values are treated as Unsigned-value
like `Integer.toUnsignedString(int)`.
Let's convert absolute value that follows minus\(-\) sign.
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<groupId>io.github.olyutorskii</groupId>
<artifactId>doubdabc</artifactId>

<version>1.103.2</version>
<version>2.101.2</version>

<packaging>jar</packaging>
<name>DoubDabC</name>
Expand Down
125 changes: 125 additions & 0 deletions src/main/java/io/github/olyutorskii/doubdabc/BcdArrays.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* License : The MIT License
* Copyright(c) 2017 olyutorskii
*/

package io.github.olyutorskii.doubdabc;

/**
* BCD array utilities but experimental.
*/
public final class BcdArrays {

private static final int INT_SLOTS =
Integer.SIZE / BcdUtils.BCD_BITSIZE;

private static final int MSB_INTMASK = 0b1 << (Integer.SIZE - 1);
private static final int LSB_INTMASK = 0b1;

private static final int BCD_MASK =
(0b1 << BcdUtils.BCD_BITSIZE) - 1;
private static final int ARABICUC_MASK = 0b0011_0000;


/**
* Hidden constructor.
*/
private BcdArrays(){
assert false;
}


/**
* Convert int value to Arabic-decimal character sequence.
*
* <p>Output nothing if value 0.
*
* <p>sign-bit is treated as unsigned.
* There is no minus-sign output.
*
* <p>DDA implementations without any instance field.
*
* @param iVal int value
* @param cbuf char output
* @param offset output start offset
* @return output length
*/
public static int int2ArabicArray(final int iVal,
final char[] cbuf, final int offset){
int iHigh = 0b0;
int iLow = 0b0;

boolean skipLeading = true;
boolean noHalfCarry = true;
int sig = 0;

for(int bitCt = 0; bitCt < Integer.SIZE; bitCt++){
final int scanMask = MSB_INTMASK >>> bitCt;
final int bitAppear = iVal & scanMask;

if(skipLeading){
if(bitAppear == 0b0) continue;
skipLeading = false;
}
sig++;

int bqVal;
int shiftedBcd;

bqVal = BcdUtils.toBiQuinary(iLow);
shiftedBcd = bqVal << 1;

if(bitAppear == 0b0){
iLow = shiftedBcd;
}else{
iLow = shiftedBcd | LSB_INTMASK;
}

// through iHigh
// if iLow has 8-bcd "67108863"(2^26-1) or lower
if(sig < 27) continue;

int halfCarry = bqVal & MSB_INTMASK;

if(noHalfCarry){
if(halfCarry == 0b0) continue;
noHalfCarry = false;
}

bqVal = BcdUtils.toBiQuinary(iHigh);
shiftedBcd = bqVal << 1;

if(halfCarry == 0b0){
iHigh = shiftedBcd;
}else{
iHigh = shiftedBcd | LSB_INTMASK;
}
}

int cidx = offset;
final int clzLow;

if(iHigh == 0b0){
clzLow = BcdUtils.clzNibble(iLow);
}else{
clzLow = 0;

final int clzHigh = BcdUtils.clzNibble(iHigh);

for(int bcdCt = clzHigh; bcdCt < INT_SLOTS; bcdCt++){
final int nibble = (iHigh >>> ((7 - bcdCt) << 2)) & BCD_MASK;
final char decimalCh = (char)(nibble | ARABICUC_MASK);
cbuf[cidx++] = decimalCh;
}
}

for(int bcdCt = clzLow; bcdCt < INT_SLOTS; bcdCt++){
final int nibble = (iLow >>> ((7 - bcdCt) << 2)) & BCD_MASK;
final char decimalCh = (char)(nibble | ARABICUC_MASK);
cbuf[cidx++] = decimalCh;
}

return cidx - offset;
}

}
98 changes: 9 additions & 89 deletions src/main/java/io/github/olyutorskii/doubdabc/BcdRegister.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,13 @@ public class BcdRegister {


private static final int PRIM_BITSIZE = Integer.SIZE;
private static final int BYTE_BITSIZE = Byte.SIZE;
private static final int BCD_BITSIZE = 4;
private static final int PRIM_SLOTS = PRIM_BITSIZE / BCD_BITSIZE;
private static final int PRIM_SLOTS =
PRIM_BITSIZE / BcdUtils.BCD_BITSIZE;

private static final int LSB_PRIMMASK = 0b1;
private static final int MSB_PRIMMASK = 0b1 << (PRIM_BITSIZE - 1);
private static final int NIBBLE_MASK = // 0b1111
(0b1 << BCD_BITSIZE) - 1;
private static final int BYTE_MASK = // 0b1111_1111
(0b1 << BYTE_BITSIZE) - 1;
(0b1 << BcdUtils.BCD_BITSIZE) - 1;

private static final int PRIMIDX_SHIFT = 3; // [ / 8] [>>> 3]
private static final int NBLIDX_MASK = // [mod 8] [& 0b111]
Expand All @@ -78,39 +75,10 @@ public class BcdRegister {
'A', 'B', 'C', 'D', 'E', 'F',
};

private static final int[] BQ_TBL;


static{
// build lookup table for Packed-BCD to Bi-quinary conversion
BQ_TBL = new int[256];

int idx = 0;
for(int highDec = 0; highDec < 16; highDec++){
int highBq;
if (highDec >= 10) highBq = 0x0;
else if(highDec >= 5) highBq = highDec + 3;
else highBq = highDec;

for(int lowDec = 0; lowDec < 16; lowDec++){
int lowBq;
if (lowDec >= 10) lowBq = 0x0;
else if(lowDec >= 5) lowBq = lowDec + 3;
else lowBq = lowDec;

int bqNblNbl = (highBq << BCD_BITSIZE) | lowBq;

BQ_TBL[idx++] = bqNblNbl;
}
}

assert idx == BQ_TBL.length;
}

static{
assert 0b1 << PRIMIDX_SHIFT == PRIM_SLOTS;
assert (-1 & NBLIDX_MASK) == PRIM_SLOTS - 1;
assert HEXCH_TBL.length == 0b1 << BCD_BITSIZE;
assert HEXCH_TBL.length == 0b1 << BcdUtils.BCD_BITSIZE;
}


Expand Down Expand Up @@ -167,42 +135,6 @@ private static int fittingContainer(int digits){
return result;
}

/**
* Convert each 4bit width PackedBCD to Bi-quinary coded decimal.
*
* <p>If each nibble(PackedBCD) in int is greater than 4,
* add 3 to nibble.
*
* <p>"nibble overflow" doesn't occur if valid PackedBCD before.
* Undefined result if invalid PackedBCD value before.
*
* <p>[0,1,2,3,4,5,6,7,8,9] → [0,1,2,3,4,8,9,A,B,C]
*
* @param iVal int value
* @return modified value
*/
public static int toBiQuinary(int iVal){
int result;
int bVal;

bVal = (iVal >>> 24);
result = BQ_TBL[bVal];

bVal = (iVal >>> 16) & BYTE_MASK;
result <<= BYTE_BITSIZE;
result |= BQ_TBL[bVal];

bVal = (iVal >>> 8) & BYTE_MASK;
result <<= BYTE_BITSIZE;
result |= BQ_TBL[bVal];

bVal = iVal & BYTE_MASK;
result <<= BYTE_BITSIZE;
result |= BQ_TBL[bVal];

return result;
}


/**
* Clear all decimal digits to Zero.
Expand Down Expand Up @@ -329,7 +261,7 @@ public boolean pushLsb(int carryOver){
for(int idx = 0; idx < buflen; idx++){
int oldVal = this.ibuf[idx];

int fixVal = toBiQuinary(oldVal);
int fixVal = BcdUtils.toBiQuinary(oldVal);
int newVal = fixVal << 1;
if(lastMsbTest != 0) newVal |= LSB_PRIMMASK;

Expand Down Expand Up @@ -388,22 +320,10 @@ private int calcPrecision(){
for(int iIdx = idxMax; iIdx >= 0; iIdx--){
int iVal = this.ibuf[iIdx];

if(iVal == 0){
result -= PRIM_SLOTS;
}else{
// Count Leading Zero nibbles(BCD)
if((iVal & 0xff_ff_00_00) == 0){
result -= 4;
iVal <<= 16;
}
if((iVal & 0xff_00_00_00) == 0){
result -= 2;
iVal <<= 8;
}
if((iVal & 0xf0_00_00_00) == 0){
result -= 1;
}
int clz = BcdUtils.clzNibble(iVal);
result -= clz;

if(clz != PRIM_SLOTS){
break;
}
}
Expand Down Expand Up @@ -460,7 +380,7 @@ private void dumpNibble(StringBuilder sb, int nibble){
int b3 = (nibble >> 3) & LSB_PRIMMASK;
int b2 = (nibble >> 2) & LSB_PRIMMASK;
int b1 = (nibble >> 1) & LSB_PRIMMASK;
int b0 = (nibble ) & LSB_PRIMMASK;
int b0 = nibble & LSB_PRIMMASK;

char c3 = HEXCH_TBL[b3];
char c2 = HEXCH_TBL[b2];
Expand Down
Loading

0 comments on commit 4e4e08a

Please sign in to comment.