--- a/Fraction.st Fri Feb 26 06:41:16 2016 +0100
+++ b/Fraction.st Sat Feb 27 12:59:25 2016 +0000
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
"
COPYRIGHT (c) 1989 by Claus Gittinger
All Rights Reserved
@@ -88,56 +90,76 @@
%{ /* NOCONTEXT */
#ifdef __SCHTEAM__
if (self == Fraction.Class) {
- return context._RETURN(new STFraction(num, den));
+ return context._RETURN(new STFraction(num, den));
}
#else
/* this check allows subclassing .. */
if (self == Fraction) {
- if (__bothSmallInteger(num, den)) {
- if (den != __mkSmallInteger(0)) {
- if (__CanDoQuickAlignedNew(sizeof(struct __Fraction))) { /* OBJECT ALLOCATION */
- OBJ newFraction;
- int spc;
- INT iDen;
+ if (__bothSmallInteger(num, den)) {
+ if (den != __mkSmallInteger(0)) {
+ if (__CanDoQuickAlignedNew(sizeof(struct __Fraction))) { /* OBJECT ALLOCATION */
+ OBJ newFraction;
+ INT iDen;
+ INT iNum;
+
+ __qCheckedAlignedNew(newFraction, sizeof(struct __Fraction));
+ __InstPtr(newFraction)->o_class = self;
+ __qSTORE(newFraction, self);
+
+ iDen = __intVal(den);
+ iNum = __intVal(num);
- __qCheckedAlignedNew(newFraction, sizeof(struct __Fraction));
- __InstPtr(newFraction)->o_class = self;
- __qSTORE(newFraction, self);
- iDen = __intVal(den);
- if (iDen != 0) {
- if (iDen < 0) {
- __FractionInstPtr(newFraction)->f_numerator = __mkSmallInteger(- __intVal(num));
- __FractionInstPtr(newFraction)->f_denominator = __mkSmallInteger(- iDen);
- } else {
- __FractionInstPtr(newFraction)->f_numerator = num;
- __FractionInstPtr(newFraction)->f_denominator = den;
- }
- if (num == __mkSmallInteger(1)) {
- /* no need to reduce */
- RETURN ( newFraction );
- }
- }
- }
- }
- }
+ if (iDen < 0) {
+ iNum = -iNum;
+ iDen = -iDen;
+ }
+ while ( (((iNum | iDen) & 1) == 0) && ( iNum != 0) && ( iDen != 0)) {
+ /* both even and non-zero */
+ iNum = iNum >> 1;
+ iDen = iDen >> 1;
+ }
+ if (iNum >= _MAX_INT) {
+ __FractionInstPtr(newFraction)->f_numerator = __MKINT(iNum);
+ } else {
+ __FractionInstPtr(newFraction)->f_numerator = __MKSMALLINT(iNum);
+ }
+ if (iDen >= _MAX_INT) {
+ __FractionInstPtr(newFraction)->f_denominator = __MKINT(iDen);
+ } else {
+ __FractionInstPtr(newFraction)->f_denominator = __MKSMALLINT(iDen);
+ }
+ if (iNum == 1) {
+ /* no need to reduce */
+ RETURN ( newFraction );
+ }
+ }
+ }
+ }
}
#endif /* not __SCHTEAM__ */
%}.
den = 0 ifTrue:[
- ^ ZeroDivide raiseRequestWith:thisContext.
+ ^ ZeroDivide raiseRequestWith:thisContext.
].
newFraction isNil ifTrue:[
- newFraction := self basicNew setNumerator:num denominator:den.
+ newFraction := self basicNew setNumerator:num denominator:den.
].
^ newFraction reduced
"
- Fraction numerator:1 denominator:3
- Fraction numerator:2 denominator:6
+ Fraction numerator:1 denominator:3
+ Fraction numerator:2 denominator:3
+ Fraction numerator:2 denominator:6
+
+ Fraction numerator:1 denominator:0 -> error
+ Fraction numerator:2 denominator:0 -> error
- Fraction numerator:1 denominator:0
- Fraction numerator:2 denominator:0
+ Fraction numerator:5 denominator:10
+ Fraction numerator:50 denominator:100
+ Fraction numerator:8 denominator:16
"
+
+ "Modified: / 27-02-2016 / 00:25:47 / cg"
!
readDecimalFractionFrom:aStringOrStream onError:exceptionBlock