Re^2: Largest integer in 64-bit perl
by ikegami (Patriarch) on May 27, 2025 at 12:17 UTC
|
What a weird lesson to take. You'll have "problems near 2**53" in those languages too! Only by using a 64-bit int can you go further. The difference is that Perl does this automatically! Perl is actually better at this.
| [reply] |
|
> The difference is that Perl does this automatically!
Is a whole number at the extreme of a mantissa's precision really converted to 64 bit integer if incremented?
My
results from binary search indicated otherwise. This might also depend on the type of operation.
Plus might do, mult might stick with float.
| [reply] |
|
[Upd: This pertains to when using addition.] An int, yes. A float, no. Just like in C. Ints are promoted to floats, but floats aren't promoted to integers. You need to cast to int to get int behaviour. Just like in C.
use v5.14;
use warnings;
my $x = 2**53;
say sprintf "%d", $x;
say sprintf "%d", $x + 1;
say sprintf "%d", int( $x ) + 1;
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
int main( void ) {
double x = 9007199254740992;
printf( "%"PRIu64"\n", (uint64_t)( x ) );
printf( "%"PRIu64"\n", (uint64_t)( x + 1 ) );
printf( "%"PRIu64"\n", (uint64_t)( (uint64_t)x + 1 ) );
}
9007199254740992
9007199254740992
9007199254740993
Other differences between floats and ints is the existence of inifinity, NaN and -0.
| [reply] [d/l] [select] |
|
|
|
|
|
use anyhow::{Context, Result};
use num::BigUint;
fn frob(n: u64) -> Result<BigUint> {
Ok((1..=n)
.into_iter()
.map(|i| BigUint::from(i))
.reduce(|a, b| a * b)
.context("fuba")?)
}
fn main() -> Result<()> {
println!("i8 {}", i8::MAX);
println!("i16 {}", i16::MAX);
println!("i32 {}", i32::MAX);
println!("i64 {}", i64::MAX);
println!("i128 {}", i128::MAX);
println!("u8 {}", u8::MAX);
println!("u16 {}", u16::MAX);
println!("u32 {}", u32::MAX);
println!("u64 {}", u64::MAX);
println!("u128 {}", u128::MAX);
println!("f32 {}", f32::MAX);
println!("f64 {}", f64::MAX);
println!("{}", frob(1000)?);
Ok(())
}
In any case, this seems to be a clearly defined matter in this case.
| [reply] [d/l] [select] |
|
The discussion in this thread is about the side effects of implicit typecasting/conversions of whole numbers to augment precision when operations may cause an overflow.
Perl does this by switching to double floats with E0 were the mantissa has 53 bits (opposed to integers with 32 or 64 bits, depending on the built).
Now from what I read on Wikipedia is Rust strictly typed.
Hence I really don't understand what your code is supposed to show.
Is there any implicit typecasting in your code?°
update
According to this tutorial: https://oylenshpeegul.gitlab.io/from-perl-to-rust/numbers.html this can't be, because coercion has to be made explicitly.
| [reply] [d/l] |
|
|
|
|
|
| [reply] |
|
| [reply] |
|
|
|
|
When I referred to "Application which require integers ...", I assumed that the reason that they required integers was that they needed mathematically exact results. Yes, the typed languages usually require you to explicitly specify an appropriate integer type. I still believe that my conclusion holds in this case.
| [reply] |
|
I'm no expert in statically typed languages..
... how many of them support x^y with integers?
Those exponentiation algorithms are normally implemented for real numbers and produce a float.
The core problem we saw and most Perl experiments here is that 2**53 is a float whose error margin doesn't allow a consistent conversion to 64 bit integer anymore.
If your statically typed language doesn't support this out-of-the-box - and Perl is build on top of C - your statement is just comparing apples with oranges.
| [reply] [d/l] |
|
|
|
|
| [reply] |
|
|