fixes signed/unsigned conversion for large integer sizes

This commit is contained in:
Eyck Jentzsch 2023-03-18 18:29:34 +01:00
parent 65461ccc48
commit 354c4a4390
3 changed files with 35 additions and 54 deletions

View File

@ -10,6 +10,7 @@
*******************************************************************************/ *******************************************************************************/
package com.minres.scviewer.database.ui.swt.internal; package com.minres.scviewer.database.ui.swt.internal;
import java.math.BigInteger;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@ -214,10 +215,10 @@ public class SignalPainter extends TrackPainter {
String label = null; String label = null;
switch(trackEntry.valueDisplay) { switch(trackEntry.valueDisplay) {
case SIGNED: case SIGNED:
label=Long.toString(last.toSignedValue()); label=last.toSignedValue().toString();
break; break;
case UNSIGNED: case UNSIGNED:
label=Long.toString(last.toUnsignedValue()); label=last.toUnsignedValue().toString();
break; break;
case BINARY: case BINARY:
label=last.toString(); label=last.toString();
@ -248,9 +249,9 @@ public class SignalPainter extends TrackPainter {
final boolean continous; final boolean continous;
final boolean signed; final boolean signed;
private long maxVal; private BigInteger maxVal;
private long minVal; private BigInteger minVal;
double yRange = (yOffsetB-yOffsetT); int yRange = (yOffsetB-yOffsetT);
public MultiBitStencilAnalog(IEventList entries, Object left, boolean continous, boolean signed) { public MultiBitStencilAnalog(IEventList entries, Object left, boolean continous, boolean signed) {
this.continous=continous; this.continous=continous;
this.signed=signed; this.signed=signed;
@ -260,28 +261,30 @@ public class SignalPainter extends TrackPainter {
maxVal=minVal; maxVal=minVal;
for (EventEntry tp : ievents) for (EventEntry tp : ievents)
for(IEvent e: tp.events) { for(IEvent e: tp.events) {
long v = signed?((BitVector)e).toSignedValue():((BitVector)e).toUnsignedValue(); BigInteger v = signed?((BitVector)e).toSignedValue():((BitVector)e).toUnsignedValue();
maxVal=Math.max(maxVal, v); maxVal=maxVal.max(v);
minVal=Math.min(minVal, v); minVal=minVal.min(v);
} }
if(maxVal==minVal) { if(maxVal==minVal) {
maxVal--; maxVal=maxVal.subtract(BigInteger.ONE);
minVal++; minVal=minVal.add(BigInteger.ONE);
} }
} else { } else {
minVal--; minVal=minVal.subtract(BigInteger.ONE);
maxVal=minVal+2; maxVal=minVal.multiply(BigInteger.valueOf(2));
} }
} }
public void draw(Projection proj, Rectangle area, IEvent left, IEvent right, int xBegin, int xEnd, boolean multiple) { public void draw(Projection proj, Rectangle area, IEvent left, IEvent right, int xBegin, int xEnd, boolean multiple) {
long leftVal = signed?((BitVector)left).toSignedValue():((BitVector)left).toUnsignedValue(); BigInteger leftVal = signed?((BitVector)left).toSignedValue():((BitVector)left).toUnsignedValue();
long rightVal= signed?((BitVector)right).toSignedValue():((BitVector)right).toUnsignedValue(); BigInteger rightVal= signed?((BitVector)right).toSignedValue():((BitVector)right).toUnsignedValue();
proj.setForeground(waveCanvas.styleProvider.getColor(WaveformColors.SIGNAL_REAL)); proj.setForeground(waveCanvas.styleProvider.getColor(WaveformColors.SIGNAL_REAL));
long range = maxVal-minVal; BigInteger range = maxVal.subtract(minVal);
int yOffsetLeft = (int) ((leftVal-minVal) * yRange / range); // ((leftVal-minVal) * yRange / range);
int yOffsetRight = (int) ((rightVal-minVal) * yRange / range); int yOffsetLeft = leftVal.subtract(minVal).multiply(BigInteger.valueOf(yRange)).divide(range).intValue();
// ((rightVal-minVal) * yRange / range);
int yOffsetRight = rightVal.subtract(minVal).multiply(BigInteger.valueOf(yRange)).divide(range).intValue();
if(continous) { if(continous) {
if (xEnd > maxPosX) { if (xEnd > maxPosX) {
proj.drawLine(xBegin, yOffsetB-yOffsetLeft, maxPosX, yOffsetB-yOffsetRight); proj.drawLine(xBegin, yOffsetB-yOffsetLeft, maxPosX, yOffsetB-yOffsetRight);

View File

@ -662,10 +662,10 @@ public class WaveformView implements IWaveformView {
else { else {
switch (entry.valueDisplay) { switch (entry.valueDisplay) {
case SIGNED: case SIGNED:
entry.currentValue = Long.toString(bv.toSignedValue()); entry.currentValue = bv.toSignedValue().toString();
break; break;
case UNSIGNED: case UNSIGNED:
entry.currentValue = Long.toString(bv.toUnsignedValue()); entry.currentValue = bv.toUnsignedValue().toString();
break; break;
case BINARY: case BINARY:
entry.currentValue=bv.toString(); entry.currentValue=bv.toString();

View File

@ -10,6 +10,8 @@
*******************************************************************************/ *******************************************************************************/
package com.minres.scviewer.database; package com.minres.scviewer.database;
import java.math.BigInteger;
/** /**
* The Class BitVector. * The Class BitVector.
*/ */
@ -174,8 +176,8 @@ public class BitVector implements IEvent {
* *
* @return the long * @return the long
*/ */
public long toUnsignedValue() { public BigInteger toUnsignedValue() {
long res = 0; BigInteger res = BigInteger.ZERO;
int bitOffset = 0; int bitOffset = 0;
int wordOffset = 0; int wordOffset = 0;
int currentWord = 0; int currentWord = 0;
@ -185,11 +187,11 @@ public class BitVector implements IEvent {
currentWord = packedValues[wordOffset]; currentWord = packedValues[wordOffset];
switch (currentWord & 3) { switch (currentWord & 3) {
case 1: case 1:
res |= 1 << i; res=res.add(BigInteger.ONE.shiftLeft(i));
break; break;
case 2: case 2:
case 3: case 3:
return 0; return BigInteger.ZERO;
default: default:
break; break;
} }
@ -209,38 +211,14 @@ public class BitVector implements IEvent {
* *
* @return the long * @return the long
*/ */
public long toSignedValue() { public BigInteger toSignedValue() {
long res = 0; BigInteger res = toUnsignedValue();
int bitOffset = 0; BigInteger pos_max = BigInteger.ONE.shiftLeft(width-1);
int wordOffset = 0; if(res.compareTo(pos_max)<0)
int currentWord = 0; return res;
int lastVal = 0; else {
// Copy values out of packed array return res.subtract(BigInteger.ONE.shiftLeft(width));
for (int i = 0; i < width; i++) {
if (bitOffset == 0)
currentWord = packedValues[wordOffset];
lastVal = 0;
switch (currentWord & 3) {
case 1:
res |= 1 << i;
lastVal = 1;
break;
case 2:
case 3:
return 0;
default:
}
bitOffset += 2;
if (bitOffset == 32) {
wordOffset++;
bitOffset = 0;
} else {
currentWord >>= 2;
}
} }
if (lastVal != 0)
res |= -1l << width;
return res;
} }
/** /**