Skip to content

Commit

Permalink
rework base a little
Browse files Browse the repository at this point in the history
  • Loading branch information
kaikalii committed Sep 22, 2024
1 parent d14ff10 commit 09330c5
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 15 deletions.
32 changes: 20 additions & 12 deletions src/algorithm/dyadic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1649,28 +1649,28 @@ impl<T: RealArrayValue> Array<T> {
if base == 0.0 {
return Err(env.error("Base cannot contain 0s"));
}
if base.is_infinite() {
return Err(env.error("Base cannot contain infinites"));
if base.is_infinite() && base.is_sign_negative() {
return Err(env.error("Base cannot contain negative infinities"));
}
if base.is_nan() {
return Err(env.error("Base cannot contain NaNs"));
}
}
let max: f64 = bases.iter().product();
let max_row_len = bases.len() + self.data.iter().any(|n| n.to_f64() >= max) as usize;
let mut new_shape = self.shape.clone();
new_shape.push(max_row_len);
new_shape.push(bases.len());
let elem_count = validate_size::<f64>(new_shape.iter().copied(), env)?;
let mut new_data = eco_vec![0.0; elem_count];
let slice = new_data.make_mut();
for (i, n) in self.data.iter().enumerate() {
let mut n = n.to_f64();
for (j, base) in bases.iter().enumerate() {
slice[i * max_row_len + j] = n.rem_euclid(*base);
n = n.div_euclid(*base);
}
if n > 0.0 {
slice[i * max_row_len + bases.len()] = n;
if n == f64::INFINITY {
slice[i * bases.len() + j] = n;
break;
} else {
slice[i * bases.len() + j] = n.rem_euclid(*base);
n = n.div_euclid(*base);
}
}
}
Ok(Array::new(new_shape, new_data))
Expand Down Expand Up @@ -1698,12 +1698,17 @@ impl<T: RealArrayValue> Array<T> {
Ok(Array::new(shape, data))
}
fn undo_base_list(&self, bases: &[f64], env: &Uiua) -> UiuaResult<Array<f64>> {
let mut max = 0.0;
for &base in bases {
if base == 0.0 {
return Err(env.error("Base cannot contain 0s"));
}
if base.is_infinite() {
return Err(env.error("Base cannot contain infinites"));
if base.is_sign_negative() {
return Err(env.error("Base cannot contain infinites"));
} else {
max = bases.iter().take_while(|&&b| !b.is_infinite()).product();
}
}
if base.is_nan() {
return Err(env.error("Base cannot contain NaNs"));
Expand All @@ -1717,7 +1722,10 @@ impl<T: RealArrayValue> Array<T> {
let mut bases = bases.to_vec();
bases.extend(repeat(1.0).take(row_len.saturating_sub(bases.len())));
for (i, chunk) in self.data.chunks_exact(row_len).enumerate() {
for (n, &b) in chunk.iter().zip(&bases).rev() {
for (n, &(mut b)) in chunk.iter().zip(&bases).rev() {
if b.is_infinite() {
b = max;
}
slice[i] = slice[i].mul_add(b, n.to_f64());
}
}
Expand Down
9 changes: 7 additions & 2 deletions src/primitive/defs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1592,11 +1592,16 @@ primitive!(
/// ex: # Experimental!
/// : base 16 256
/// When passed an array of numbers, [base] treats each digit as having a different base.
/// Anything left over will be added as the most significant digit.
/// Any remainder will be truncated.
/// ex: # Experimental!
/// : base [10 2] 123
/// : base [10 2] 35 # Truncated
/// ex: # Experimental!
/// : base [60 60 24 365.25] now
/// If you want to keep the remainder, use [infinity].
/// ex: # Experimental!
/// : base [10 2 ∞] 35
/// ex: # Experimental!
/// : base [60 60 24 365.25 ∞] now
/// Non-integer bases are supported.
/// ex: # Experimental!
/// : base π [η π τ]
Expand Down
2 changes: 1 addition & 1 deletion todo.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Uiua Todo

- 0.13
- `base` tweak
- `anti` modifier
- `un on drop`
- `un under`
- Non-scalar `fill take`
- Update language tour
- Update design page
Expand Down

0 comments on commit 09330c5

Please sign in to comment.