[Nickle] nickle: Branch 'master'

Keith Packard keithp at keithp.com
Sun Dec 9 21:08:54 PST 2007


 float.c   |   13 +------------
 integer.c |    6 +++---
 value.c   |   23 ++++++++++++++++++++---
 value.h   |    1 +
 4 files changed, 25 insertions(+), 18 deletions(-)

New commits:
commit f78bf021e6bff9f422188f068a7a1b4aaa28d57f
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Dec 9 21:08:47 2007 -0800

    Make // and % operators modulus division operators.
    
    Herry S Warren Jr. defines three kinds of division --
    truncating, floor and modulus. For all three kinds he
    requires a simple invarient:
    
    	dividend = quotient * divisor + remainder
    
    Modulus division additionaly requires
    
     	0 <= remainder < abs (divisor)
    
    Floor division sets:
    
    	quotient = floor (dividend / divisor)
    	remainder = dividend - quotient * divisor
    
    Truncating division has
    
    	quotient = round_towards_zero (dividend / divisor)
    	remainder = dividend - quotient * divisor
    
    We select modulus division as it makes the most sense when you treat the
    values as a ring centered at zero.

diff --git a/float.c b/float.c
index 1c7a33e..9b7281b 100644
--- a/float.c
+++ b/float.c
@@ -408,17 +408,6 @@ FloatDivide (Value av, Value bv, int expandOk)
 }
 
 static Value
-FloatMod (Value av, Value bv, int expandOk)
-{
-    ENTER ();
-    Value   q;
-
-    q = Floor (Divide (av, bv));
-    av = Minus (av, Times (q, bv));
-    RETURN (av);
-}
-
-static Value
 FloatLess (Value av, Value bv, int expandOk)
 {
     ENTER ();
@@ -1006,7 +995,7 @@ ValueRep   FloatRep = {
 	FloatTimes,
 	FloatDivide,
 	NumericDiv,
-	FloatMod,
+	NumericMod,
 	FloatLess,
 	FloatEqual,
 	0,
diff --git a/integer.c b/integer.c
index 25646ad..266611e 100644
--- a/integer.c
+++ b/integer.c
@@ -144,10 +144,10 @@ IntegerDiv (Value av, Value bv, int expandOk)
     }
     quo = NaturalDivide (IMag(a), IMag(b), &rem);
     sign = Positive;
-    if ((ISign(a) == Positive) != (ISign(b) == Positive))
+    if (ISign (a) != ISign (b))
 	sign = Negative;
-    if (sign == Negative && !NaturalZero (rem))
-	quo = NaturalPlus (quo, one_natural);
+    if (ISign (a) == Negative && !NaturalZero (rem))
+        quo = NaturalPlus (quo, one_natural);
     RETURN (NewInteger (sign, quo));
 }
 
diff --git a/value.c b/value.c
index 1edf860..78024cf 100644
--- a/value.c
+++ b/value.c
@@ -163,8 +163,6 @@ BinaryOperate (Value av, Value bv, BinaryOp operator)
 		break;
 	    case FirstPositive:
 		r = - (a / -b);
-		if (a % -b)
-		    --r;
 		break;
 	    case SecondPositive:
 		r = -(-a / b);
@@ -174,6 +172,8 @@ BinaryOperate (Value av, Value bv, BinaryOp operator)
 	    case BothNegative:
 	    default:
 		r = -a / -b;
+		if (-a % -b)
+		    r++;
 		break;
 	    }
 	    return NewInt (r);
@@ -301,7 +301,24 @@ Value
 NumericDiv (Value av, Value bv, int expandOk)
 {
     ENTER ();
-    RETURN (Floor (Divide (av, bv)));
+
+    av = Divide (av, bv);
+    if (Negativep (bv))
+	av = Ceil (av);
+    else
+	av = Floor (av);
+    RETURN (av);
+}
+
+Value
+NumericMod (Value av, Value bv, int expandOk)
+{
+    ENTER ();
+    Value   q;
+
+    q = NumericDiv (av, bv, expandOk);
+    av = Minus (av, Times (q, bv));
+    RETURN (av);
 }
 
 Value
diff --git a/value.h b/value.h
index e94428f..af33302 100644
--- a/value.h
+++ b/value.h
@@ -1035,6 +1035,7 @@ Type	*BuildArrayType (Type *type, int ndim, ...);
 Value	BinaryOperate (Value av, Value bv, BinaryOp operator);
 Value	UnaryOperate (Value v, UnaryOp operator);
 Value	NumericDiv (Value av, Value bv, int expandOk);
+Value	NumericMod (Value av, Value bv, int expandOk);
 
 # define	OK_TRUNC	1
 


More information about the Nickle mailing list