Closed and-vil closed 1 year ago
This is a floating-point rounding error, as most numbers in Uiua are represented as IEEE doubles. Consider the output of this Rust program.
That rust playground link contains no rust program
@Garmelon Try this link. If that fails, here's some code and output:
Rust code:
fn main() {
let err_num: f32 = 14472334024676221f32;
println!("Errored number (f32): {}", err_num);
let err_num: f64 = 14472334024676221f64; //shadowing `err_num`
println!("Also errored number (f64): {}", err_num);
let num: u64 = 14472334024676221u64;
println!("Number (u64): {}", num);
let num: u128 = 14472334024676221u128; //shadowing `num`
println!("Also number (u128): {}", num);
}
Output:
Errored number (f32): 14472334000000000
Also errored number (f64): 14472334024676220
Number (u64): 14472334024676221
Also number (u128): 14472334024676221
In an ideal world, it might be nice to have strictly integral-type matrices that are fully integrally bounded to use integral types under the hood, but given that matrices can be float-valued, it makes sense to implement them in that domain alone, especially since one could use modulo or other algos to just remap into the appropriate range. Implementing some sort of type-switching that could do so would allow for some more flexibility, but I would imagine would be a nightmare to implement, even if possible. This isn't truly an issue at this point, especially since there are other ways of approaching this particular problem.
P.S. This same f64 (or equivalent-size IEEE double) numeric limitation applies in APL/J and BQN (when also testing using similar online interpreters/environments), so it seems fairly standard (linguistically speaking, anyhow) for operations structured like this to remain strictly float-valued.
The interpreter currently uses both an f64
array type and a u8
array type.
The u8
type is mostly for space efficiency when reading files in and sometimes for booleans.
While it would not be hard to add an integral type, it would be a lot of code both to write and for the Rust compiler to chew on, further increasing the compile times of the interpreter itself.
It is a combinatorics problem.
A new array type wouldn't necessarily be a lot to add.
A new array type that has to behave like the other number types would be a lot, as most functions on arrays have to type check, and each new number type would double the number of number-type checks. Some of these could be eliminated by doing a catch-all convert-to-f64 for some operations, but this would also defeat the purpose of adding an integral type in the first place.
Using the Matrix exponentiation Uiuism on Chrome on Windows 10, both up-to-date, (this is the direct Pad link, but is located at the bottom of https://www.uiua.org/isms) on the 2-D basis matrix for the Fibonacci sequence, there are computation errors for exponents greater than 78.
For reference, the 79th term of the Fibonacci sequence should be 14472334024676221, but has a zero in the ones place if run with the Uiuism. For an example of this, here is a link to a Pad with the Fibonacci basis matrix and an n-value of 78, with n+1 in the first matrix cell of the result. As sequence terms increase past 79, this continues for successive terms, and there is a loss in precision as terms increase, but the initial digits of successive terms are correct until hitting their respective limits.
Since this error only occurs above the 32-bit unsigned integer limit of 4294967295 and for some values under the signed 64-bit limit of 9223372036854775807, this may be unintended behavior.