Index: defs.h
===================================================================
RCS file: /cvsroot/findutils/findutils/find/defs.h,v
retrieving revision 1.36
diff -u -r1.36 defs.h
--- defs.h	12 Feb 2005 21:11:04 -0000	1.36
+++ defs.h	4 Mar 2005 09:57:22 -0000
@@ -155,6 +155,12 @@
   COMP_EQ
 };
 
+enum rounding_type
+{
+  ROUND_UP,			/* default (e.g. -size) */
+  ROUND_NONE			/* for -size <N, -size >N, -size =N */
+};
+
 enum permissions_type
 {
   PERM_AT_LEAST,
@@ -207,6 +213,7 @@
 struct size_val
 {
   enum comparison_type kind;
+  enum rounding_type   rounding;
   int blocksize;
   uintmax_t size;
 };
Index: parser.c
===================================================================
RCS file: /cvsroot/findutils/findutils/find/parser.c,v
retrieving revision 1.60
diff -u -r1.60 parser.c
--- parser.c	12 Feb 2005 21:11:04 -0000	1.60
+++ parser.c	4 Mar 2005 09:57:23 -0000
@@ -147,7 +147,7 @@
 static boolean insert_exec_ok PARAMS((const char *action, boolean (*func )(), char *argv[], int *arg_ptr));
 static boolean get_num_days PARAMS((char *str, uintmax_t *num_days, enum comparison_type *comp_type));
 static boolean insert_time PARAMS((char *argv[], int *arg_ptr, PFB pred));
-static boolean get_num PARAMS((char *str, uintmax_t *num, enum comparison_type *comp_type));
+static boolean get_num PARAMS((char *str, uintmax_t *num, enum comparison_type *comp_type, enum rounding_type *round_type));
 static boolean insert_num PARAMS((char *argv[], int *arg_ptr, PFB pred));
 static FILE *open_output_file PARAMS((char *path));
 
@@ -1359,6 +1359,7 @@
   struct predicate *our_pred;
   uintmax_t num;
   enum comparison_type c_type;
+  enum rounding_type   r_type;
   int blksize = 512;
   int len;
 
@@ -1414,10 +1415,11 @@
     default:
       error (1, 0, _("invalid -size type `%c'"), argv[*arg_ptr][len - 1]);
     }
-  if (!get_num (argv[*arg_ptr], &num, &c_type))
+  if (!get_num (argv[*arg_ptr], &num, &c_type, &r_type))
     return (false);
   our_pred = insert_primary (pred_size);
   our_pred->args.size.kind = c_type;
+  our_pred->args.size.rounding = r_type;
   our_pred->args.size.blocksize = blksize;
   our_pred->args.size.size = num;
   (*arg_ptr)++;
@@ -1477,12 +1479,14 @@
   struct predicate *our_pred;
   uintmax_t num_days;
   enum comparison_type c_type;
+  enum rounding_type   r_type;
   time_t t;
 
   if ((argv == NULL) || (argv[*arg_ptr] == NULL))
     return (false);
-  if (!get_num (argv[*arg_ptr], &num_days, &c_type))
+  if (!get_num (argv[*arg_ptr], &num_days, &c_type, &r_type))
     return (false);
+
   t = num_days * DAYSECS;
   our_pred = insert_primary (pred_used);
   our_pred->args.info.kind = c_type;
@@ -2176,14 +2180,18 @@
 static boolean
 get_num_days (char *str, uintmax_t *num_days, enum comparison_type *comp_type)
 {
-  boolean r = get_num (str, num_days, comp_type);
+  enum rounding_type r_type;
+  
+  boolean r = get_num (str, num_days, comp_type, &r_type);
   if (r)
-    switch (*comp_type)
-      {
-      case COMP_LT: *comp_type = COMP_GT; break;
-      case COMP_GT: *comp_type = COMP_LT; break;
-      default: break;
-      }
+    {
+      switch (*comp_type)
+	{
+	case COMP_LT: *comp_type = COMP_GT; break;
+	case COMP_GT: *comp_type = COMP_LT; break;
+	default: break;
+	}
+    }
   return r;
 }
 
@@ -2270,22 +2278,37 @@
    Return true if all okay, false if input error.  */
 
 static boolean
-get_num (char *str, uintmax_t *num, enum comparison_type *comp_type)
+get_num (char *str, uintmax_t *num,
+	 enum comparison_type *comp_type,
+	 enum rounding_type *round_type)
 {
   if (str == NULL)
     return (false);
   switch (str[0])
     {
     case '+':
+    case '>':
       *comp_type = COMP_GT;
+      *round_type = (str[0] == '>' ? ROUND_NONE : ROUND_UP);
       str++;
       break;
+
     case '-':
+    case '<':
       *comp_type = COMP_LT;
+      *round_type = (str[0] == '<' ? ROUND_NONE : ROUND_UP);
       str++;
       break;
+      
+    case '=':
+      *comp_type = COMP_EQ;
+      *round_type = ROUND_NONE;
+      str++;
+      break;
+      
     default:
       *comp_type = COMP_EQ;
+      *round_type = ROUND_UP;
       break;
     }
 
@@ -2310,10 +2333,11 @@
   struct predicate *our_pred;
   uintmax_t num;
   enum comparison_type c_type;
-
+  enum rounding_type   r_type;
+  
   if ((argv == NULL) || (argv[*arg_ptr] == NULL))
     return (false);
-  if (!get_num (argv[*arg_ptr], &num, &c_type))
+  if (!get_num (argv[*arg_ptr], &num, &c_type, &r_type))
     return (false);
   our_pred = insert_primary (pred);
   our_pred->args.info.kind = c_type;
Index: pred.c
===================================================================
RCS file: /cvsroot/findutils/findutils/find/pred.c,v
retrieving revision 1.56
diff -u -r1.56 pred.c
--- pred.c	23 Feb 2005 00:27:28 -0000	1.56
+++ pred.c	4 Mar 2005 09:57:23 -0000
@@ -1238,27 +1238,47 @@
 boolean
 pred_size (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
 {
-  uintmax_t f_val;
+  uintmax_t f_val, remainder;
 
   (void) pathname;
-  f_val = ((stat_buf->st_size / pred_ptr->args.size.blocksize)
-	   + (stat_buf->st_size % pred_ptr->args.size.blocksize != 0));
+  f_val     = stat_buf->st_size / pred_ptr->args.size.blocksize;
+  remainder = stat_buf->st_size % pred_ptr->args.size.blocksize;
+  
+  if (pred_ptr->args.size.rounding == ROUND_UP)
+    {
+      if (remainder)
+	f_val += 1;
+    }
+  
   switch (pred_ptr->args.size.kind)
     {
     case COMP_GT:
       if (f_val > pred_ptr->args.size.size)
-	return (true);
+	{
+	  return true;
+	}
+      else if (pred_ptr->args.size.rounding == ROUND_NONE)
+	{
+	  return (f_val == pred_ptr->args.size.size) && (remainder > 0);
+	}
       break;
+      
     case COMP_LT:
       if (f_val < pred_ptr->args.size.size)
-	return (true);
+	return true;
       break;
+      
     case COMP_EQ:
       if (f_val == pred_ptr->args.size.size)
-	return (true);
+	{
+	  if (pred_ptr->args.size.rounding == ROUND_NONE)
+	    return remainder == 0;
+	  else 
+	    return true;
+	}
       break;
     }
-  return (false);
+  return false;
 }
 
 boolean
