You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2012/09/06 13:55:51 UTC
svn commit: r1381565 - in /jena/trunk/jena-tdb/src:
main/java/com/hp/hpl/jena/tdb/store/DecimalNode.java
test/java/com/hp/hpl/jena/tdb/store/TestNodeId.java
Author: andy
Date: Thu Sep 6 11:55:50 2012
New Revision: 1381565
URL: http://svn.apache.org/viewvc?rev=1381565&view=rev
Log:
JENA-317 : Be more careful checking ranges.
Modified:
jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/store/DecimalNode.java
jena/trunk/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/store/TestNodeId.java
Modified: jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/store/DecimalNode.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/store/DecimalNode.java?rev=1381565&r1=1381564&r2=1381565&view=diff
==============================================================================
--- jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/store/DecimalNode.java (original)
+++ jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/store/DecimalNode.java Thu Sep 6 11:55:50 2012
@@ -31,48 +31,52 @@ public class DecimalNode
BigDecimal decimal = null ;
- // 8 bits of scale, signed 48 bits of value.
+ // signed 8 bits of scale, signed 48 bits of value.
+ // Decimal precision is 47 bits (it's signed) or around 14 places.
// Not finance industry accuracy nor XSD (18 places minimum) but still useful.
- static final long MAX = (1L<<48) ;
- static final BigInteger MAX_I = BigInteger.valueOf(MAX) ;
- static final BigInteger MIN_I = BigInteger.valueOf(-MAX) ;
+ static final int SCALE_LEN = 8 ;
+ static final int VALUE_LEN = 48 ;
+
+ static final long MAX_VALUE = (1L<< (VALUE_LEN-1) )-1 ;
+ static final long MIN_VALUE = -(1L<< (VALUE_LEN-1) ) ;
+
+ static final int MAX_SCALE = (1<< (SCALE_LEN-1) )-1 ;
+ static final int MIN_SCALE = -(1<< (SCALE_LEN-1) ) ;
+
+ static final BigInteger MAX_I = BigInteger.valueOf(MAX_VALUE) ;
+ static final BigInteger MIN_I = BigInteger.valueOf(MIN_VALUE) ;
// Bits counts
- static private int SCALE_LO = 56-8 ;
+ static private int SCALE_LO = 56-SCALE_LEN ;
static private int SCALE_HI = 56 ; // Exclusive index
static private int VALUE_LO = 0 ;
- static private int VALUE_HI = VALUE_LO+48 ;
-
- // Decimal precision is 47 bits (it's signed) or around 14 places.
- private int scale ; // Limted to byte value range. +255 - -256
- private long value ; // 48 bits of precision (8 bits type, 8 bits scale).
+ static private int VALUE_HI = VALUE_LO+VALUE_LEN ;
+ private int scale ;
+ private long value ;
public static DecimalNode valueOf(BigDecimal decimal)
{
int scale = decimal.scale() ;
BigInteger bigInt = decimal.unscaledValue() ;
+
if ( bigInt.compareTo(MAX_I) > 0 || bigInt.compareTo(MIN_I) < 0 )
- {
- // This check also makes sure that bigInt.logValue is safe.
- // Too big for 56 bits
- //log.warn("Value out of range: ("+decimal.scale()+","+decimal.unscaledValue()+")") ;
+ // This check makes sure that bigInt.longValue() is safe
return null ;
- }
return valueOf(bigInt.longValue(), scale) ;
}
public static DecimalNode valueOf(long binValue, int scale)
{
- if ( scale >= 128 || scale < -128 )
+ if ( scale < MIN_SCALE || scale > MAX_SCALE )
{
//log.warn("Scale out of range: ("+binValue+","+scale+")") ;
return null ;
}
- if ( Math.abs(binValue) > MAX )
+ if ( binValue < MIN_VALUE || binValue > MAX_VALUE )
{
//log.warn("Value out of range: ("+binValue+","+scale+")") ;
return null ;
@@ -95,6 +99,7 @@ public class DecimalNode
long v = BitsLong.pack(0, NodeId.DECIMAL, 56, 64) ;
v = BitsLong.pack(v, scale, SCALE_LO, SCALE_HI) ;
v = BitsLong.pack(v, value, VALUE_LO, VALUE_HI) ;
+ // No need to do something about negative numbers
return v ;
}
@@ -113,8 +118,8 @@ public class DecimalNode
int scale = (int)BitsLong.unpack(v, SCALE_LO, SCALE_HI) ;
long value = BitsLong.unpack(v, VALUE_LO, VALUE_HI) ;
// Sign extend value.
- if ( BitsLong.isSet(value, 47) )
- value = value | -1L<<48 ;
+ if ( BitsLong.isSet(value, VALUE_LEN-1) )
+ value = value | -1L<<(VALUE_LEN) ;
return BigDecimal.valueOf(value, scale) ;
}
Modified: jena/trunk/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/store/TestNodeId.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/store/TestNodeId.java?rev=1381565&r1=1381564&r2=1381565&view=diff
==============================================================================
--- jena/trunk/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/store/TestNodeId.java (original)
+++ jena/trunk/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/store/TestNodeId.java Thu Sep 6 11:55:50 2012
@@ -85,6 +85,15 @@ public class TestNodeId extends BaseTest
@Test public void nodeId_decimal_4()
{ test("-1.0", NodeFactory.parseNode("-1.0")) ; }
+ // This number has > 47 bits of value : 2412.80478192688
+ @Test public void nodeId_decimal_5()
+ { test("2412.80478192688", (Node)null) ; }
+
+ // This number has > 47 bits of value : -2412.80478192688
+ @Test public void nodeId_decimal_6()
+ { test("-2412.80478192688", (Node)null) ; }
+
+
@Test public void nodeId_dateTime_01()
{ test("'2008-04-28T15:36:15+01:00'^^xsd:dateTime") ; }
@@ -194,12 +203,12 @@ public class TestNodeId extends BaseTest
NodeId nodeId = NodeId.inline(n) ;
if ( correct == null )
{
- assertNull(nodeId) ;
+ assertNull("Expected no encoding: got: "+nodeId, nodeId) ;
return ;
}
-
+ assertNotNull("Expected inlining: "+n, nodeId) ;
Node n2 = NodeId.extract(nodeId) ;
- assertNotNull(n2) ;
+ assertNotNull("Expected recovery", n2) ;
String s = "("+correct.getLiteralLexicalForm()+","+n2.getLiteralLexicalForm()+")" ;