rust-lang / rfcs

RFCs for changes to Rust
https://rust-lang.github.io/rfcs/
Apache License 2.0
5.94k stars 1.57k forks source link

Implement 48-bit integer types. #2903

Open deeprobin opened 4 years ago

deeprobin commented 4 years ago

I would be in favor of implementing u48 and i48. There are few CPUs that support 48-bit integers otherwise you could represent it as 16-bit and 32-bit numbers internally. But I guess this optimization is already done by LLVM.

Reasons why you should implement this:

tesuji commented 4 years ago

48-bit integers is not even supported by Tier-1 Rust support. So I don't think that it is worth to have that 48-bit primitive integer type.

le-jzr commented 4 years ago

Wouldn't this just be a storage format? I doubt any modern CPU would ever implement this directly, but using it for storage in cases where 32b is too small and 64b is too wasteful could make sense. But that could be easily implemented in library.

comex commented 4 years ago

Once const generics are done, we could have a generic uint<N> type that worked for any N, either as a crate or in libstd.

For now... apparently there's a crate that implements u1-u127 and i1-i127.

kennytm commented 4 years ago

ux's u48 is backed by a u64 (occupies 8 bytes), while what OP wants is likely a 6-byte type.

deeprobin commented 4 years ago

I mean you could implement this type since LLVM supports it too. And it is not harmful to implement it, if you don't want to use it, you don't have to use it.

deeprobin commented 4 years ago

Once const generics are done, we could have a generic uint<N> type that worked for any N, either as a crate or in libstd.

For now... apparently there's a crate that implements u1-u127 and i1-i127.

That's a good start. You can use uint<48> for example and create a type alias 'u48'.

sfackler commented 4 years ago

ux's u48 is backed by a u64 (occupies 8 bytes), while what OP wants is likely a 6-byte type.

Unless u48 would be less aligned than u32, it's going to be 8 bytes with padding regardless.

I mean you could implement this type since LLVM supports it too.

"can be written in LLVM IR" is not the same thing as "actually works". It took months of work to get the 128 bit integer types to a level of functionality on all of the relevant targets that they could actually be stabilized.

And it is not harmful to implement it, if you don't want to use it, you don't have to use it.

All features have a cost.

deeprobin commented 4 years ago

"can be written in LLVM IR" is not the same thing as "actually works". It took months of work to get the 128-bit integer types to a level of functionality on all of the relevant targets that they could actually be stabilized.

Sure, of course, but time should not be the factor in rejecting the issue. And because 128-bit integers have been implemented, it may be easier, since a foundation stone has already been laid.

All features have a cost.

Certainly, the u48 in the build has its costs. But finally compiled it has more advantages than disadvantages.

kennytm commented 4 years ago

Unless u48 would be less aligned than u32, it's going to be 8 bytes with padding regardless.

Yes you could make it [u16; 3].

Additionally, being a u64 means it has 8-byte alignment while a (u32, u16) only needs 4-byte alignment (and [u16; 3] has 2-byte alignment).

There are many choices what a u48 should behave but no clear answer which one should be chosen, unlike the other power-of-2 primitive types.

clarfonthey commented 4 years ago

Once const generics are done, we could have a generic uint<N> type that worked for any N, either as a crate or in libstd.

Oh hey, I wrote an RFC for this too.

Chubercik commented 3 months ago

Yes you could make it [u16; 3].

I just published the i48 crate, which represents the i48 type exactly like that, contributions welcome :)

kennytm commented 3 months ago

There's already an intx ­package that provides all 8N-bit integers (16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128) with minimal storage and alignment = 1 (they wrap [u8; N]).

Chubercik commented 3 months ago

Thanks for the heads up, it's [u8; 6] now.