saxbophone / arby

Arbitrary precision arithmetic in C++, even at compile-time
https://saxbophone.com/arby/
Mozilla Public License 2.0
8 stars 1 forks source link

Consider different rules for selecting digits StorageType #111

Closed saxbophone closed 2 years ago

saxbophone commented 2 years ago

Currently, we just take the type of int and pick StorageType as the unsigned type that is one level smaller than it, with OverflowType as the unsigned type the same size as int.

This means we miss out on opportunities to have bigger digits when e.g. a 64-bit platform has int = 32-bit.

It might be worth experimenting by changing GetStorageType to take the type of both int and uintmax_t (or maybe unsigned int and uintmax_t), so that we can reliably pick the largest type for StorageType for which there exists a larger unsigned type, to use for OverflowType. Knowing both unsigned int and uintmax_t will help us make sure we don't exceed the biggest type supported on the platform being used, whilst also giving us a good hint at what is the "natural" (most-efficient?) type to use on the given system.

saxbophone commented 2 years ago

Because uintmax_t is a separate type, we can't just put that into the template.

Instead, we should use std::numeric_limits<>::digits to select an appropriately-sized fixed-width type from the number of bits

saxbophone commented 2 years ago

This is a simplified version of the decision process.

In reality, rather than hard-code to unsigned int, unsigned long and unsigned short, we will use std::numeric_limits<>::digits in combination with the fixed-width types.

flowchart TD
    A[Start] --> B{unsigned int < uintmax_t?}
    B -->|Yes| C[StorageType = unsigned int] --> D[OverflowType = unsigned long]
    B -->|No| E[StorageType = unsigned short] --> F[OverflowType = unsigned int]
    D --> G[End]
    F --> G