From: Luc Teirlinck Date: Wed, 26 Nov 2003 19:23:58 +0000 (+0000) Subject: (number-sequence): Improve handling of floating point arguments X-Git-Tag: ttn-vms-21-2-B4~8264 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=2c1385edb656815975976a72081e4b134ed716e9;p=emacs.git (number-sequence): Improve handling of floating point arguments (suggested by Kim Storm). Allow negative arguments. --- diff --git a/lisp/subr.el b/lisp/subr.el index f5e5891b96a..9dc6c2ba6ec 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -191,20 +191,41 @@ If N is bigger than the length of X, return X." (defun number-sequence (from &optional to inc) "Return a sequence of numbers from FROM to TO (both inclusive) as a list. -INC is the increment used between numbers in the sequence. -So, the Nth element of the list is (+ FROM (* N INC)) where N counts from -zero. -If INC is nil, it defaults to 1 (one). -If TO is nil, it defaults to FROM. -If TO is less than FROM, the value is nil. -Note that FROM, TO and INC can be integer or float." - (if (not to) +INC is the increment used between numbers in the sequence and defaults to 1. +So, the Nth element of the list is \(+ FROM \(* N INC)) where N counts from +zero. TO is only included if there is an N for which TO = FROM + N * INC. +If TO is nil or numerically equal to FROM, return \(FROM). +If INC is positive and TO is less than FROM, or INC is negative +and TO is larger than FROM, return nil. +If INC is zero and TO is neither nil nor numerically equal to +FROM, signal an error. + +This function is primarily designed for integer arguments. +Nevertheless, FROM, TO and INC can be integer or float. However, +floating point arithmetic is inexact. For instance, depending on +the machine, it may quite well happen that +\(number-sequence 0.4 0.6 0.2) returns the one element list \(0.4), +whereas \(number-sequence 0.4 0.8 0.2) returns a list with three +elements. Thus, if some of the arguments are floats and one wants +to make sure that TO is included, one may have to explicitly write +TO as \(+ FROM \(* N INC)) or use a variable whose value was +computed with this exact expression. Alternatively, you can, +of course, also replace TO with a slightly larger value +\(or a slightly more negative value if INC is negative)." + (if (or (not to) (= from to)) (list from) (or inc (setq inc 1)) - (let (seq) - (while (<= from to) - (setq seq (cons from seq) - from (+ from inc))) + (when (zerop inc) (error "The increment can not be zero")) + (let (seq (n 0) (next from)) + (if (> inc 0) + (while (<= next to) + (setq seq (cons next seq) + n (1+ n) + next (+ from (* n inc)))) + (while (>= next to) + (setq seq (cons next seq) + n (1+ n) + next (+ from (* n inc))))) (nreverse seq)))) (defun remove (elt seq)