Add a math module to the standard lib

I need some rudimentary stdlib stuff for the tutorial.

Closes #1042
This commit is contained in:
Marijn Haverbeke 2011-10-18 13:45:17 +02:00
parent d9d0782b5f
commit 71a4a66135
6 changed files with 72 additions and 21 deletions

View file

@ -1305,17 +1305,17 @@ fn valid_range_bounds(l1: @ast::lit, l2: @ast::lit) -> bool {
let s2 = lit_as_float(l2);
let f1 = std::float::from_str(s1);
let f2 = std::float::from_str(s2);
ret *util::common::min(f1, f2) == f1
ret std::math::min(f1, f2) == f1
}
ast::lit_uint(_) | ast::lit_char(_) {
let u1 = lit_as_uint(l1);
let u2 = lit_as_uint(l2);
ret *util::common::min(u1, u2) == u1
ret std::math::min(u1, u2) == u1
}
_ {
let i1 = lit_as_int(l1);
let i2 = lit_as_int(l2);
ret *util::common::min(i1, i2) == i1
ret std::math::min(i1, i2) == i1
}
}
}

View file

@ -1,4 +1,5 @@
import std::{str, map, uint, int, option};
import std::math::{max, min};
import std::map::hashmap;
import std::option::{none, some};
import syntax::ast;
@ -131,7 +132,7 @@ fn lit_in_range(l: @ast::lit, m1: @ast::lit, m2: @ast::lit) -> bool {
irange(i1, i2) {
alt l.node {
ast::lit_int(i3) | ast::lit_mach_int(_, i3) {
i3 >= *min(i1, i2) && i3 <= *max(i1, i2)
i3 >= min(i1, i2) && i3 <= max(i1, i2)
}
_ { fail }
}
@ -139,7 +140,7 @@ fn lit_in_range(l: @ast::lit, m1: @ast::lit, m2: @ast::lit) -> bool {
urange(u1, u2) {
alt l.node {
ast::lit_uint(u3) {
u3 >= *min(u1, u2) && u3 <= *max(u1, u2)
u3 >= min(u1, u2) && u3 <= max(u1, u2)
}
_ { fail }
}
@ -147,8 +148,8 @@ fn lit_in_range(l: @ast::lit, m1: @ast::lit, m2: @ast::lit) -> bool {
crange(c1, c2) {
alt l.node {
ast::lit_char(c3) {
(c3 as uint) >= *min(c1 as uint, c2 as uint) &&
(c3 as uint) <= *max(c1 as uint, c2 as uint)
(c3 as uint) >= min(c1 as uint, c2 as uint) &&
(c3 as uint) <= max(c1 as uint, c2 as uint)
}
_ { fail }
}
@ -156,8 +157,8 @@ fn lit_in_range(l: @ast::lit, m1: @ast::lit, m2: @ast::lit) -> bool {
frange(f1, f2) {
alt l.node {
ast::lit_float(f3) | ast::lit_mach_float(_, f3) {
std::float::from_str(f3) >= *min(f1, f2) &&
std::float::from_str(f3) <= *max(f1, f2)
std::float::from_str(f3) >= min(f1, f2) &&
std::float::from_str(f3) <= max(f1, f2)
}
_ { fail }
}
@ -165,19 +166,11 @@ fn lit_in_range(l: @ast::lit, m1: @ast::lit, m2: @ast::lit) -> bool {
}
}
fn min<@T>(x: T, y: T) -> @T {
ret @(if x > y { y } else { x });
}
fn max<@T>(x: T, y: T) -> @T {
ret @(if x > y { x } else { y });
}
fn ranges_overlap<@T>(a1: T, a2: T, b1: T, b2: T) -> bool {
let min1 = *min(a1, a2);
let max1 = *max(a1, a2);
let min2 = *min(b1, b2);
let max2 = *max(b1, b2);
let min1 = min(a1, a2);
let max1 = max(a1, a2);
let min2 = min(b1, b2);
let max2 = max(b1, b2);
ret (min1 >= min2 && max1 <= max2) || (min1 <= min2 && max1 >= min2) ||
(min1 >= min2 && min1 <= max2) || (max1 >= min2 && max1 <= max2);
}

22
src/lib/math.rs Normal file
View file

@ -0,0 +1,22 @@
native "llvm" mod llvm {
fn sqrt(n: float) -> float = "sqrt.f64";
fn sin(n: float) -> float = "sin.f64";
fn asin(n: float) -> float = "asin.f64";
fn cos(n: float) -> float = "cos.f64";
fn acos(n: float) -> float = "acos.f64";
fn tan(n: float) -> float = "tan.f64";
fn atan(n: float) -> float = "atan.f64";
}
fn sqrt(x: float) -> float { llvm::sqrt(x) }
fn sin(x: float) -> float { llvm::sin(x) }
fn cos(x: float) -> float { llvm::cos(x) }
fn tan(x: float) -> float { llvm::tan(x) }
fn asin(x: float) -> float { llvm::asin(x) }
fn acos(x: float) -> float { llvm::acos(x) }
fn atan(x: float) -> float { llvm::atan(x) }
const pi: float = 3.141592653589793;
fn min<@T>(x: T, y: T) -> T { x < y ? x : y }
fn max<@T>(x: T, y: T) -> T { x < y ? y : x }

View file

@ -97,6 +97,7 @@ mod ptr;
mod test;
mod unsafe;
mod term;
mod math;
#[cfg(unicode)]
mod unicode;

34
src/test/stdtest/math.rs Normal file
View file

@ -0,0 +1,34 @@
use std;
import std::math::*;
#[test]
fn test_sqrt() {
assert sqrt(9.0) == 3.0;
assert sqrt(4.0) == 2.0;
assert sqrt(1.0) == 1.0;
assert sqrt(0.0) == 0.0;
}
#[test]
fn test_max_min() {
assert max(0, 1) == 1;
assert min(0, 1) == 0;
assert max(0, -1) == 0;
assert min(0, -1) == -1;
assert max(0.0, 1.0) == 1.0;
assert min(0.0, 1.0) == 0.0;
}
#[test]
fn test_angle() {
fn angle(vec: (float, float)) -> float {
alt vec {
(0f, y) when y < 0f { 1.5 * std::math::pi }
(0f, y) { 0.5 * std::math::pi }
(x, y) { std::math::atan(y / x) }
}
}
assert angle((1f, 0f)) == 0f;
assert angle((1f, 1f)) == 0.25 * pi;
assert angle((0f, 1f)) == 0.5 * pi;
}

View file

@ -30,6 +30,7 @@ mod task;
mod test;
mod uint;
mod float;
mod math;
// Local Variables:
// mode: rust