LargeInteger.st
changeset 3431 ae8f96921fcc
parent 3428 fb8dbb5dce40
child 3438 2e64ef848871
equal deleted inserted replaced
3430:e42beefa71e7 3431:ae8f96921fcc
   231 !
   231 !
   232 
   232 
   233 value:aSmallInteger
   233 value:aSmallInteger
   234     "create and return a new LargeInteger with value taken from
   234     "create and return a new LargeInteger with value taken from
   235      the argument, aSmallInteger.
   235      the argument, aSmallInteger.
   236      Notice: this should be only used internally, since such small
   236      Notice: 
   237      largeIntegers do not normally occur in the system.
   237 	this should be only used internally, since such small
   238      May change without notice."
   238         largeIntegers do not normally occur in the system.
   239 
   239 	(They are used by myself)
       
   240      May change/be removed without notice."
       
   241 
       
   242 %{  /* NOCONTEXT */
       
   243     if (__isSmallInteger(aSmallInteger)) {
       
   244         INT v = __intVal(aSmallInteger);
       
   245 
       
   246         RETURN(__MKLARGEINT(v));
       
   247     }
       
   248 %}.
       
   249 
       
   250     "/ should never be reached
   240     ^ self basicNew value:aSmallInteger
   251     ^ self basicNew value:aSmallInteger
   241 
   252 
   242     "LargeInteger value:3689"
   253     "LargeInteger value:3689"
   243 ! !
   254 ! !
   244 
   255 
   595 
   606 
   596 	bp = (unsigned char *)(__ByteArrayInstPtr(__INST(digitByteArray))->ba_element);
   607 	bp = (unsigned char *)(__ByteArrayInstPtr(__INST(digitByteArray))->ba_element);
   597 	idx = __intVal(sz);
   608 	idx = __intVal(sz);
   598 
   609 
   599 	while ((idx > 1) && (bp[idx-1] == 0)) idx--;
   610 	while ((idx > 1) && (bp[idx-1] == 0)) idx--;
       
   611 
   600 	if (idx == sizeof(INT)) {
   612 	if (idx == sizeof(INT)) {
   601 #if defined(i386) || defined(alpha) /* actually: LSBFIRST */
   613 #if defined(alpha64)
   602 	    if ( ((INT *)bp)[0] == _MIN_INT)
   614 	    if ( ((unsigned INT *)bp)[0] == 0x4000000000000000L)
   603 #else
   615 #else
       
   616 # if defined(i386) /* actually: LSBFIRST */
       
   617 	    if ( ((unsigned INT *)bp)[0] == 0x40000000)
       
   618 # else
   604 	    /*
   619 	    /*
   605 	     * generic code
   620 	     * generic code
   606 	     */
   621 	     */
   607 	    if ((bp[idx-1] == 0x40)
   622 	    if ((bp[idx-1] == 0x40)
   608 	     && (bp[idx-2] == 0)
   623 	     && (bp[idx-2] == 0)
   609 	     && (bp[idx-3] == 0)
   624 	     && (bp[idx-3] == 0)
   610 	     && (bp[idx-4] == 0)
   625 	     && (bp[idx-4] == 0)
   611 # ifdef alpha64
   626 #  ifdef alpha64
   612 	     && (bp[idx-5] == 0)
   627 	     && (bp[idx-5] == 0)
   613 	     && (bp[idx-6] == 0)
   628 	     && (bp[idx-6] == 0)
   614 	     && (bp[idx-7] == 0)
   629 	     && (bp[idx-7] == 0)
   615 	     && (bp[idx-8] == 0)
   630 	     && (bp[idx-8] == 0)
       
   631 #  endif
       
   632 	    ) 
   616 # endif
   633 # endif
   617 	    ) 
       
   618 #endif
   634 #endif
   619 	    {
   635 	    {
   620 		RETURN (__MKSMALLINT(_MIN_INT));
   636 		RETURN (__MKSMALLINT(_MIN_INT));
   621 	    }
   637 	    }
   622 	}
   638 	}
  1072     ].
  1088     ].
  1073     ^ self
  1089     ^ self
  1074 !
  1090 !
  1075 
  1091 
  1076 value:aSmallInteger
  1092 value:aSmallInteger
  1077     "return a new LargeInteger with value taken from a SmallInteger.
  1093     "setup my contents to represent the same value as aSmallInteger.
  1078      This method will fail, if the argument is not a smallInteger.
  1094      This method will fail, if the argument is not a smallInteger.
  1079      This will create an unnormalized LargeInt (by purpose) if asked for."
  1095      This should only be used internally, 
       
  1096      since it will create an unnormalized LargeInt (by purpose) if asked for."
  1080 
  1097 
  1081     |absValue 
  1098     |absValue 
  1082      b1 "{ Class: SmallInteger }"
  1099      b1 "{ Class: SmallInteger }"
  1083      b2 "{ Class: SmallInteger }"
  1100      b2 "{ Class: SmallInteger }"
  1084      b3 "{ Class: SmallInteger }"
  1101      b3 "{ Class: SmallInteger }"
  1085      b4 "{ Class: SmallInteger }"
  1102      b4 "{ Class: SmallInteger }"
  1086      b5 "{ Class: SmallInteger }"
  1103      b5 "{ Class: SmallInteger }"
  1087      b6 "{ Class: SmallInteger }"
  1104      b6 "{ Class: SmallInteger }"
  1088      b7 "{ Class: SmallInteger }"|
  1105      b7 "{ Class: SmallInteger }"|
  1089 
  1106 
  1090 %{
  1107     "
  1091     /* the common case first ... */
  1108      could have simply created a 4-byte largeinteger and normalize it. 
  1092     if (__isSmallInteger(aSmallInteger)) {
  1109      The code below does the normalize right away, avoiding the
  1093 	INT v = __intVal(aSmallInteger);
       
  1094 
       
  1095 #ifdef alpha64
       
  1096         if (v & 0xFF00000000000000L) {
       
  1097 	    RETURN(__MKLARGEINT(v));
       
  1098 	}
       
  1099 #else
       
  1100         if (v & 0xFF000000L) {
       
  1101 	    RETURN(__MKLARGEINT(v));
       
  1102 	}
       
  1103 #endif
       
  1104     }
       
  1105 %}.
       
  1106     "
       
  1107      could have simply created a 4-byte largeinteger and normalize
       
  1108      it; the code below does the normalize right away, avoiding the
       
  1109      overhead of producing any intermediate byte-arrays (and the scanning)
  1110      overhead of producing any intermediate byte-arrays (and the scanning)
  1110     "
  1111     "
  1111     (aSmallInteger == 0) ifTrue: [
  1112     (aSmallInteger == 0) ifTrue: [
  1112 	digitByteArray := ByteArray with:0.
  1113 	digitByteArray := ByteArray with:0.
  1113 	sign := 0.
  1114 	sign := 0.
  1114 	^ self
  1115 	^ self
  1115     ].
  1116     ].
       
  1117 
  1116     (aSmallInteger < 0) ifTrue: [
  1118     (aSmallInteger < 0) ifTrue: [
  1117 	sign := -1.
  1119 	sign := -1.
  1118 	absValue := aSmallInteger negated
  1120 	absValue := aSmallInteger negated
  1119     ] ifFalse: [
  1121     ] ifFalse: [
  1120 	sign := 1.
  1122 	sign := 1.
  1121 	absValue := aSmallInteger
  1123 	absValue := aSmallInteger
  1122     ].
  1124     ].
       
  1125 
  1123     b1 := absValue bitAnd:16rFF.
  1126     b1 := absValue bitAnd:16rFF.
  1124     absValue := absValue bitShift:-8.
  1127     absValue := absValue bitShift:-8.
  1125     absValue == 0 ifTrue:[
  1128     absValue == 0 ifTrue:[
  1126 	digitByteArray := ByteArray with:b1
  1129 	digitByteArray := ByteArray with:b1
  1127     ] ifFalse:[
  1130     ] ifFalse:[
  2623 ! !
  2626 ! !
  2624 
  2627 
  2625 !LargeInteger class methodsFor:'documentation'!
  2628 !LargeInteger class methodsFor:'documentation'!
  2626 
  2629 
  2627 version
  2630 version
  2628     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.67 1998-05-08 12:08:09 cg Exp $'
  2631     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.68 1998-05-08 13:15:16 cg Exp $'
  2629 ! !
  2632 ! !