       else
         x * fact2(x-2)
     fact2(n)
+
+
+  FLOOR: (args)->
+    @checkArgumentSize(args, 2)
+    expr = @expectNumber(args[0])
+    digit = @expectNumber(args[1])
+    if digit == 0
+      @error(ERROR_DIV0)
+    if expr >= 0 && digit < 0
+      @error(ERROR_NUM)
+    Math.floor(expr/digit) * digit
+
+  "FLOOR.PRECISE": (args)->
+    @checkArgumentSize(args, 1, 2)
+    if args.length == 1
+      args.push 1
+    args[1] = Math.abs(@expectNumber(args[1]))
+    if args[1] == 0
+      return 0
+    @FLOOR(args)
+
+
+  "FLOOR.MATH": (args)->
+    @checkArgumentSize(args, 1, 3)
+    if args.length == 1
+      args.push 1
+    expr = @expectNumber(args[0])
+    digit = Math.abs(@expectNumber(args[1]))
+    sign = 1
+    if digit == 0
+      return 0
+    if args.length == 3
+      sign = Math.sign(expr)
+      expr = Math.abs(expr)
+    sign * @FLOOR([expr, digit])
+
 
   GCD: (args)->
     @checkArgumentSize(args, 1, Number.MAX_VALUE)

    sum


  ROUND: (args)->
    @checkArgumentSize(args, 2)
    expr = @expectNumber(args[0])
    sign = Math.sign(expr)
    expr = Math.abs(expr)
    n = Math.floor(@expectNumber(args[1]))
    digit = Math.pow(10, n)
    sign * Math.round(expr*digit) / digit


  ROUNDUP: (args)->
    @checkArgumentSize(args, 2)
    expr = @expectNumber(args[0])
    sign = Math.sign(expr)
    expr = Math.abs(expr)
    n = Math.floor(@expectNumber(args[1]))
    digit = Math.pow(10, n)
    sign * @CEILING([expr, digit])

  ROUNDDOWN: (args)->
    @checkArgumentSize(args, 2)
    expr = @expectNumber(args[0])
    sign = Math.sign(expr)
    expr = Math.abs(expr)
    n = Math.floor(@expectNumber(args[1]))
    digit = Math.pow(10, n)
    sign * @FLOOR([expr, digit])

  CEILING: (args)->
    @checkArgumentSize(args, 2)
    expr = @expectNumber(args[0])
    digit = @expectNumber(args[1])
    if digit == 0
      return 0
    if expr >= 0 && digit < 0
      @error(ERROR_NUM)
    Math.ceil(expr/digit) * digit

  "CEILING.PRECISE": (args)->
    @checkArgumentSize(args, 1, 2)
    if args.length == 1
      args.push 1
    args[1] = Math.abs(@expectNumber(args[1]))
    @CEILING(args)


  "CEILING.MATH": (args)->
    @checkArgumentSize(args, 1, 3)
    if args.length == 1
      args.push 1
    expr = @expectNumber(args[0])
    digit = Math.abs(@expectNumber(args[1]))
    sign = 1
    if digit == 0
      return 0
    if args.length == 3
      sign = Math.sign(expr)
      expr = Math.abs(expr)
    sign * @CEILING([expr, digit])



  FLOOR: (args)->
    @checkArgumentSize(args, 2)
    expr = @expectNumber(args[0])
    digit = @expectNumber(args[1])
    if digit == 0
      @error(ERROR_DIV0)
    if expr >= 0 && digit < 0
      @error(ERROR_NUM)
    Math.floor(expr/digit) * digit

  "FLOOR.PRECISE": (args)->
    @checkArgumentSize(args, 1, 2)
    if args.length == 1
      args.push 1
    args[1] = Math.abs(@expectNumber(args[1]))
    if args[1] == 0
      return 0
    @FLOOR(args)


  "FLOOR.MATH": (args)->
    @checkArgumentSize(args, 1, 3)
    if args.length == 1
      args.push 1
    expr = @expectNumber(args[0])
    digit = Math.abs(@expectNumber(args[1]))
    sign = 1
    if digit == 0
      return 0
    if args.length == 3
      sign = Math.sign(expr)
      expr = Math.abs(expr)
    sign * @FLOOR([expr, digit])


  TRUNC: (args)->
    @checkArgumentSize(args, 1, 2)
    if args.length == 1
      args.push 0

    @ROUNDDOWN(args)


  IF: (args)->
    @checkArgumentSize(args, 3)
    [cond, true_expr, false_expr] = args
    cond = @getValue(cond)
    if Utils.isNumber(cond)
      cond = cond == 1
    else if !Utils.isBoolean(cond)
      @error(ERROR_VALUE)

    if cond
      true_expr
    else
      false_expr



  error:(err)->

      g = @__gcd__(n, g)
    g

  IF: (args)->
    @checkArgumentSize(args, 3)
    [cond, true_expr, false_expr] = args
    cond = @getValue(cond)
    if Utils.isNumber(cond)
      cond = cond == 1
    else if !Utils.isBoolean(cond)
      @error(ERROR_VALUE)

    if cond
      true_expr
    else
      false_expr

  INT: (args)->
    @checkArgumentSize(args, 1)
    args.push 1
    @FLOOR(args)

  "ISO.CEILING":@::["CEILING.PRECISE"]

