Skip to main content
deleted 570 characters in body
Source Link
Davislor
  • 9.2k
  • 19
  • 39

I gave some feedback on an earlier version of this, but there was one thing that I didn’t go into detail about.

The Double_Word Type

Currently, you use this in four places: addition, subtraction, multiplication and division. You’ve moved the definition (which previously had some problems) into a different file that you didn’t show us.

Addition and subtraction don’t technically need this type, although it’s likely faster than the alternatives. If the result of an ddition is larger than either of its addends, it overflowed, and you can carry one bit.

Division doesn’t need it either; you can do unsigned long division using only / and %, although some architectures might have speed-ups.

So that leaves multiplication, where you need some way to get the high word of the product. You have a few imperfect options:

  • For language lawyers, the only completely compatible, standard-conforming solution is to keep an array of unsigned short int and widen them to unsigned long int. A short is guaranteed to be no more than 16 bits wide, and a long no less than 32 bits wide, so these will work to hold all the bits of the product. There isn’t any larger type guaranteed to be half the size of some other type; int, long, long long, uint_least32_t, uint_least64_t and intmax_t are all allowed to be 64 bits or more wide, and uint32_t is not guaranteed to exist.
  • In practical, real-world use, all compilers provide uint32_t and uint64_t. This is an especially good option if you want a simple learning exercise and will not use this in production. However,
  • It would be more efficient to store data in chunks of the native word size of the target machine. In the real world, size_t holds an unsigned machine word and operations on them will be fast. A good way to test how wide this is in the preprocessor is the constant SIZE_MAX in <stdint.h>.
  • When size_t is larger than 32 bits (#if SIZE_MAX > 0xFFFFFFFFUL), there isn’t a standard type guaranteed to be large enough to hold the product of two of them. However, most compilers offer extensions that solve this:
    • uintmax_t is theoretically supposed to be the widest supported unsigned integral type (although this is frequently not true), so if any type can hold the square of SIZE_MAX, it might be this. And you can check portably.
    • GCC, Clang and ICX have an unsigned __int128 type.
    • MSVC for 64-bit targets has a __umulh intrinsic function in <intrin.h> that returns the upper word of the product of two unsigned 64-bit numbers, and others for add-with carry. You could use these as non-portable alternatives to a double word.
    • Some compilers have uint128_t as an extension, which might be added to the Standard in the future.

I gave some feedback on an earlier version of this, but there was one thing that I didn’t go into detail about.

The Double_Word Type

Currently, you use this in four places: addition, subtraction, multiplication and division. You’ve moved the definition (which previously had some problems) into a different file that you didn’t show us.

Addition and subtraction don’t technically need this type, although it’s likely faster than the alternatives. If the result of an ddition is larger than either of its addends, it overflowed, and you can carry one bit.

Division doesn’t need it either; you can do unsigned long division using only / and %, although some architectures might have speed-ups.

So that leaves multiplication, where you need some way to get the high word of the product. You have a few imperfect options:

  • For language lawyers, the only completely compatible, standard-conforming solution is to keep an array of unsigned short int and widen them to unsigned long int. A short is guaranteed to be no more than 16 bits wide, and a long no less than 32 bits wide, so these will work to hold all the bits of the product. There isn’t any larger type guaranteed to be half the size of some other type; int, long, long long, uint_least32_t, uint_least64_t and intmax_t are all allowed to be 64 bits or more wide, and uint32_t is not guaranteed to exist.
  • In practical, real-world use, all compilers provide uint32_t and uint64_t. This is an especially good option if you want a simple learning exercise and will not use this in production. However,
  • It would be more efficient to store data in chunks of the native word size of the target machine. In the real world, size_t holds an unsigned machine word and operations on them will be fast. A good way to test how wide this is in the preprocessor is the constant SIZE_MAX in <stdint.h>.
  • When size_t is larger than 32 bits (#if SIZE_MAX > 0xFFFFFFFFUL), there isn’t a standard type guaranteed to be large enough to hold the product of two of them. However, most compilers offer extensions that solve this:
    • uintmax_t is theoretically supposed to be the widest supported unsigned integral type (although this is frequently not true), so if any type can hold the square of SIZE_MAX, it might be this. And you can check portably.
    • GCC, Clang and ICX have an unsigned __int128 type.
    • MSVC for 64-bit targets has a __umulh intrinsic function in <intrin.h> that returns the upper word of the product of two unsigned 64-bit numbers, and others for add-with carry. You could use these as non-portable alternatives to a double word.
    • Some compilers have uint128_t as an extension, which might be added to the Standard in the future.

I gave some feedback on an earlier version of this, but there was one thing that I didn’t go into detail about.

The Double_Word Type

Currently, you use this in four places: addition, subtraction, multiplication and division. You’ve moved the definition (which previously had some problems) into a different file that you didn’t show us.

Addition and subtraction don’t technically need this type, although it’s likely faster than the alternatives. If the result of an ddition is larger than either of its addends, it overflowed, and you can carry one bit.

Division doesn’t need it either; you can do unsigned long division using only / and %, although some architectures might have speed-ups.

So that leaves multiplication, where you need some way to get the high word of the product. You have a few imperfect options:

  • In practical, real-world use, all compilers provide uint32_t and uint64_t. This is an especially good option if you want a simple learning exercise and will not use this in production. However,
  • It would be more efficient to store data in chunks of the native word size of the target machine. In the real world, size_t holds an unsigned machine word and operations on them will be fast. A good way to test how wide this is in the preprocessor is the constant SIZE_MAX in <stdint.h>.
  • When size_t is larger than 32 bits (#if SIZE_MAX > 0xFFFFFFFFUL), there isn’t a standard type guaranteed to be large enough to hold the product of two of them. However, most compilers offer extensions that solve this:
    • uintmax_t is theoretically supposed to be the widest supported unsigned integral type (although this is frequently not true), so if any type can hold the square of SIZE_MAX, it might be this. And you can check portably.
    • GCC, Clang and ICX have an unsigned __int128 type.
    • MSVC for 64-bit targets has a __umulh intrinsic function in <intrin.h> that returns the upper word of the product of two unsigned 64-bit numbers, and others for add-with carry. You could use these as non-portable alternatives to a double word.
    • Some compilers have uint128_t as an extension, which might be added to the Standard in the future.
added 252 characters in body
Source Link
Davislor
  • 9.2k
  • 19
  • 39

I gave some feedback on an earlier version of this, but there was one thing that I didn’t go into detail about.

The Double_Word Type

Currently, you use this in four places: addition, subtraction, multiplication and division. You’ve moved the definition (which previously had some problems) into a different file that you didn’t show us.

Addition and subtraction don’t technically need this type, although it’s likely faster than the alternatives. If the result of an ddition is larger than either of its addends, it overflowed, and you can carry one bit.

Division doesn’t need it either; you can do unsigned long division using only / and %, although some architectures might have speed-ups.

So that leaves multiplication, where you need some way to get the high word of the product. You have a few imperfect options:

  • For language lawyers, the only completely compatible, standard-conforming solution is to keep an array of unsigned short int and widen them to unsigned long int. A short is guaranteed to be no more than 16 bits wide, and a long no less than 32 bits wide, so these will work to hold all the bits of the product. There isn’t any larger type guaranteed to be half the size of some other type; int, long, long long, uint_least32_t, uint_least64_t and intmax_t are all allowed to be 64 bits or more wide, and uint32_t is not guaranteed to exist.
  • In practical, real-world use, all compilers provide uint32_t and uint64_t. This is an especially good option if you want a simple learning exercise and will not use this in production. However,
  • It would be more efficient to store data in chunks of the native word size of the target machine. In the real world, size_t holds an unsigned machine word and operations on them will be fast. A good way to test how wide this is in the preprocessor is the constant SIZE_MAX in <stdint.h>.
  • When size_t is larger than 32 bits (#if SIZE_MAX > 0xFFFFFFFFUL), there isn’t a standard type guaranteed to be large enough to hold the product of two of them. However, most compilers offer extensions that solve this:
    • uintmax_t is theoretically supposed to be the widest supported unsigned integral type (although this is frequently not true) in the real world, so if any type can hold the square of SIZE_MAX, it might be this. And you can check portably.
    • GCC, Clang and ICX have an unsigned __int128 type.
    • MSVC for 64-bit targets has a __umulh intrinsic function in <intrin.h> that returns the upper word of the product of two unsigned 64-bit numbers, and others for add-with carry. You could use these as non-portable alternatives to a double word.
    • Some compilers have uint128_t as an extension, which might be added to the Standard in the future.

I gave some feedback on an earlier version of this, but there was one thing that I didn’t go into detail about.

The Double_Word Type

Currently, you use this in four places: addition, subtraction, multiplication and division. You’ve moved the definition (which previously had some problems) into a different file that you didn’t show us.

Addition and subtraction don’t technically need this type, although it’s likely faster than the alternatives. If the result of an ddition is larger than either of its addends, it overflowed, and you can carry one bit.

Division doesn’t need it either; you can do unsigned long division using only / and %, although some architectures might have speed-ups.

So that leaves multiplication, where you need some way to get the high word of the product. You have a few imperfect options:

  • For language lawyers, the only completely compatible, standard-conforming solution is to keep an array of unsigned short int and widen them to unsigned long int. A short is guaranteed to be no more than 16 bits wide, and a long no less than 32 bits wide, so these will work to hold all the bits of the product. There isn’t any larger type guaranteed to be half the size of some other type; int, long, long long, uint_least32_t, uint_least64_t and intmax_t are all allowed to be 64 bits or more wide, and uint32_t is not guaranteed to exist.
  • In practical, real-world use, all compilers provide uint32_t and uint64_t. This is an especially good option if you want a simple learning exercise and will not use this in production. However,
  • It would be more efficient to store data in chunks of the native word size of the target machine. In the real world, size_t holds an unsigned machine word and operations on them will be fast. A good way to test how wide this is in the preprocessor is the constant SIZE_MAX in <stdint.h>.
  • When size_t is larger than 32 bits (#if SIZE_MAX > 0xFFFFFFFFUL), there isn’t a standard type guaranteed to be large enough to hold the product of two of them. However, most compilers offer extensions that solve this:
    • uintmax_t is theoretically supposed to be the widest supported unsigned integral type (although this is frequently not true) in the real world, so if any type can hold the square of SIZE_MAX, it might be this. And you can check portably.
    • GCC, Clang and ICX have an unsigned __int128 type.
    • MSVC for 64-bit targets has a __umulh intrinsic function in <intrin.h> that returns the upper word of the product of two unsigned 64-bit numbers, and others for add-with carry. You could use these as non-portable alternatives to a double word.
    • Some compilers have uint128_t as an extension, which might be added to the Standard in the future.

I gave some feedback on an earlier version of this, but there was one thing that I didn’t go into detail about.

The Double_Word Type

Currently, you use this in four places: addition, subtraction, multiplication and division. You’ve moved the definition (which previously had some problems) into a different file that you didn’t show us.

Addition and subtraction don’t technically need this type, although it’s likely faster than the alternatives. If the result of an ddition is larger than either of its addends, it overflowed, and you can carry one bit.

Division doesn’t need it either; you can do unsigned long division using only / and %, although some architectures might have speed-ups.

So that leaves multiplication, where you need some way to get the high word of the product. You have a few imperfect options:

  • For language lawyers, the only completely compatible, standard-conforming solution is to keep an array of unsigned short int and widen them to unsigned long int. A short is guaranteed to be no more than 16 bits wide, and a long no less than 32 bits wide, so these will work to hold all the bits of the product. There isn’t any larger type guaranteed to be half the size of some other type; int, long, long long, uint_least32_t, uint_least64_t and intmax_t are all allowed to be 64 bits or more wide, and uint32_t is not guaranteed to exist.
  • In practical, real-world use, all compilers provide uint32_t and uint64_t. This is an especially good option if you want a simple learning exercise and will not use this in production. However,
  • It would be more efficient to store data in chunks of the native word size of the target machine. In the real world, size_t holds an unsigned machine word and operations on them will be fast. A good way to test how wide this is in the preprocessor is the constant SIZE_MAX in <stdint.h>.
  • When size_t is larger than 32 bits (#if SIZE_MAX > 0xFFFFFFFFUL), there isn’t a standard type guaranteed to be large enough to hold the product of two of them. However, most compilers offer extensions that solve this:
    • uintmax_t is theoretically supposed to be the widest supported unsigned integral type (although this is frequently not true), so if any type can hold the square of SIZE_MAX, it might be this. And you can check portably.
    • GCC, Clang and ICX have an unsigned __int128 type.
    • MSVC for 64-bit targets has a __umulh intrinsic function in <intrin.h> that returns the upper word of the product of two unsigned 64-bit numbers, and others for add-with carry. You could use these as non-portable alternatives to a double word.
    • Some compilers have uint128_t as an extension, which might be added to the Standard in the future.
added 252 characters in body
Source Link
Davislor
  • 9.2k
  • 19
  • 39

I gave some feedback on an earlier version of this, but there was one thing that I didn’t go into detail about.

The Double_Word Type

Currently, you use this in four places: addition, subtraction, multiplication and division. You’ve moved the definition (which previously had some problems) into a different file that you didn’t show us.

Addition and subtraction don’t technically need this type, although it’s likely faster than the alternatives. If the result of an ddition is larger than either of its addends, it overflowed, and you can carry one bit.

Division doesn’t need it either; you can do unsigned long division using only / and %, although some architectures might have speed-ups.

So that leaves multiplication, where you need some way to get the high word of the product. You have a few imperfect options:

  • For language lawyers, the only completely compatible, standard-conforming solution is to keep an array of unsigned short int and widen them to unsigned long int. A short is guaranteed to be no more than 16 bits wide, and a long no less than 32 bits wide, so these will work to hold all the bits of the product. There isn’t any larger type guaranteed to be half the size of some other type; int, long, long long, uint_least32_t and, uint_least64_t and intmax_t are all allowed to be 64 bits or more wide, and uint32_t is not guaranteed to exist.
  • In practical, real-world use, all mainstream compilers provide uint32_t and uint64_t. HoweverThis is an especially good option if you want a simple learning exercise and will not use this in production. However,
  • It would be more efficient to store data in chunks of the native word size of the target machine. In the real world, size_t holds an unsigned machine word and operations on them will be fast. A good way to test how wide this is in the preprocessor is the constant SIZE_MAX in <stdint.h>.
  • When size_t is larger than 32 bits (#if SIZE_MAX > 0xFFFFFFFFUL), there isn’t a standard type guaranteed to be large enough to hold the product of two of them. However, most compilers offer extensions that solve this:
    • uintmax_t is theoretically supposed to be the widest supported unsigned integral type (although this is frequently not true) in the real world, so if any type can hold the square of SIZE_MAX, it might be this. And you can check portably.
    • GCC, Clang and ICX have an unsigned __int128 type.
    • MSVC for 64-bit targets has a __umulh intrinsic function in <intrin.h> that returns the upper word of the product of two unsigned 64-bit numbers, and others for add-with carry. You could use these as non-portable alternatives to a double word.
    • Some compilers have uint128_t as an extension, which might be added to the Standard in the future.

I gave some feedback on an earlier version of this, but there was one thing that I didn’t go into detail about.

The Double_Word Type

Currently, you use this in four places: addition, subtraction, multiplication and division. You’ve moved the definition (which previously had some problems) into a different file that you didn’t show us.

Addition and subtraction don’t technically need this type, although it’s likely faster than the alternatives. If the result of an ddition is larger than either of its addends, it overflowed, and you can carry one bit.

Division doesn’t need it either; you can do unsigned long division using only / and %, although some architectures might have speed-ups.

So that leaves multiplication, where you need some way to get the high word of the product. You have a few imperfect options:

  • For language lawyers, the only completely compatible, standard-conforming solution is to keep an array of unsigned short int and widen them to unsigned long int. A short is guaranteed to be no more than 16 bits wide, and a long no less than 32 bits wide, so these will work to hold all the bits of the product. There isn’t any larger type guaranteed to be half the size of some other type; int, long, long long, uint_least32_t and uint_least64_t are all allowed to be 64 bits or more wide, and uint32_t is not guaranteed to exist.
  • In practical, real-world use, all mainstream compilers provide uint32_t and uint64_t. However,
  • It would be more efficient to store data in chunks of the native word size of the target machine. In the real world, size_t holds an unsigned machine word and operations on them will be fast. A good way to test how wide this is in the preprocessor is the constant SIZE_MAX in <stdint.h>.
  • When size_t is larger than 32 bits (#if SIZE_MAX > 0xFFFFFFFFUL), there isn’t a standard type guaranteed to be large enough to hold the product of two of them. However, most compilers offer extensions that solve this:
    • GCC, Clang and ICX have an unsigned __int128 type.
    • MSVC for 64-bit targets has a __umulh intrinsic function in <intrin.h> that returns the upper word of the product of two unsigned 64-bit numbers, and others for add-with carry. You could use these as non-portable alternatives to a double word.
    • Some compilers have uint128_t as an extension, which might be added to the Standard in the future.

I gave some feedback on an earlier version of this, but there was one thing that I didn’t go into detail about.

The Double_Word Type

Currently, you use this in four places: addition, subtraction, multiplication and division. You’ve moved the definition (which previously had some problems) into a different file that you didn’t show us.

Addition and subtraction don’t technically need this type, although it’s likely faster than the alternatives. If the result of an ddition is larger than either of its addends, it overflowed, and you can carry one bit.

Division doesn’t need it either; you can do unsigned long division using only / and %, although some architectures might have speed-ups.

So that leaves multiplication, where you need some way to get the high word of the product. You have a few imperfect options:

  • For language lawyers, the only completely compatible, standard-conforming solution is to keep an array of unsigned short int and widen them to unsigned long int. A short is guaranteed to be no more than 16 bits wide, and a long no less than 32 bits wide, so these will work to hold all the bits of the product. There isn’t any larger type guaranteed to be half the size of some other type; int, long, long long, uint_least32_t, uint_least64_t and intmax_t are all allowed to be 64 bits or more wide, and uint32_t is not guaranteed to exist.
  • In practical, real-world use, all compilers provide uint32_t and uint64_t. This is an especially good option if you want a simple learning exercise and will not use this in production. However,
  • It would be more efficient to store data in chunks of the native word size of the target machine. In the real world, size_t holds an unsigned machine word and operations on them will be fast. A good way to test how wide this is in the preprocessor is the constant SIZE_MAX in <stdint.h>.
  • When size_t is larger than 32 bits (#if SIZE_MAX > 0xFFFFFFFFUL), there isn’t a standard type guaranteed to be large enough to hold the product of two of them. However, most compilers offer extensions that solve this:
    • uintmax_t is theoretically supposed to be the widest supported unsigned integral type (although this is frequently not true) in the real world, so if any type can hold the square of SIZE_MAX, it might be this. And you can check portably.
    • GCC, Clang and ICX have an unsigned __int128 type.
    • MSVC for 64-bit targets has a __umulh intrinsic function in <intrin.h> that returns the upper word of the product of two unsigned 64-bit numbers, and others for add-with carry. You could use these as non-portable alternatives to a double word.
    • Some compilers have uint128_t as an extension, which might be added to the Standard in the future.
Source Link
Davislor
  • 9.2k
  • 19
  • 39
Loading