object *sqrt_proc(object *arguments) { if (is_fixnum(car(arguments))) { return make_floatnum(sqrt((car(arguments))->data.fixnum.value)); } else { return make_floatnum(sqrt((car(arguments))->data.floatnum.value)); } }
//TODO: Add integer reduction, consider using fpisanint() instead of fmod approach object *remainder_proc(object *arguments) { if (is_floatnum(car(arguments)) || is_floatnum(cadr(arguments))) { return make_floatnum( fmod((is_floatnum(car(arguments)) ? (car(arguments))->data.floatnum.value : (double)(car(arguments))->data.fixnum.value), (is_floatnum(cadr(arguments)) ? (cadr(arguments))->data.floatnum.value : (double)(cadr(arguments))->data.fixnum.value)) ); } else { return make_fixnum( ((car(arguments) )->data.fixnum.value) % ((cadr(arguments))->data.fixnum.value) ); } }
//TODO: Add integer reduction, consider using fpisanint() instead of fmod approach object *quotient_proc(object *arguments) { if (is_floatnum(car(arguments)) || is_floatnum(cadr(arguments))) { return make_floatnum( (is_floatnum(car(arguments)) ? (car(arguments))->data.floatnum.value : (double)(car(arguments))->data.fixnum.value) / (is_floatnum(cadr(arguments)) ? (cadr(arguments))->data.floatnum.value : (double)(cadr(arguments))->data.fixnum.value) ); } else { return make_fixnum( ((car(arguments) )->data.fixnum.value) / ((cadr(arguments))->data.fixnum.value) ); } }
object *mul_proc(object *arguments) { long result = 1; double result2 = 1.0; bool real = false; while (!is_empty(arguments)) { real = is_floatnum(car(arguments)); if (real) result2 *= (car(arguments))->data.floatnum.value; else result *= (car(arguments))->data.fixnum.value; arguments = cdr(arguments); } //TODO: Consider using fpisanint() instead of fmod approach if ((real || (result2 != 0.0)) && fmod(result2, 1) != 0.0) return make_floatnum(result2 * (double)result); else if (real || (result2 != 0.0)) return make_fixnum(lround(result2 * (double)result)); else return make_fixnum(result); }
object *sub_proc(object *arguments) { long result; double result2 = 0.0; bool real_mode = false; bool real = false; real = is_floatnum(car(arguments)); if (real) { real_mode = true; result2 = (car(arguments))->data.floatnum.value; } else result = (car(arguments))->data.fixnum.value; while (!is_empty(arguments = cdr(arguments))) { if (real_mode) { real = is_floatnum(car(arguments)); if (real) result2 -= (car(arguments))->data.floatnum.value; else result2 -= (double)(car(arguments))->data.fixnum.value; } else { real = is_floatnum(car(arguments)); if (real) { result2 = (double)result - (car(arguments))->data.floatnum.value; real_mode = true; } else result -= (car(arguments))->data.fixnum.value; } } //TODO: Consider using fpisanint() instead of fmod approach if (real_mode && fmod(result2, 1) != 0.0) return make_floatnum(result2); else if (real_mode) return make_fixnum(lround(result2)); else return make_fixnum(result); }