Menu

- Learn
- Documentation
  - Language Reference
  - Library Reference
  - Command-line Reference
  - Feature Overview
  - Articles
- Downloads
- Packages
- Community
  - Blog
  - Orgs using D
  - Twitter
  - Forums
  - IRC
  - Community Discord
  - Wiki
  - GitHub
  - Issues
  - Get involved
  - Contributors
  - Foundation
  - Security Team
  - Donate
  - Sponsors
- Resources
  - Tour
  - Books
  - Tutorials
  - Tools
  - Editors
  - IDEs
  - run.dlang.io
  - Visual D
  - Acknowledgments
  - D Style
  - Glossary
  - Sitemap

Search
Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

# core.checkedint

This module implements integral arithmetic primitives that check for out-of-range results.
Integral arithmetic operators operate on fixed width types. Results that are not representable in those fixed widths are silently truncated to fit. This module offers integral arithmetic primitives that produce the same results, but set an 'overflow' flag when such truncation occurs. The setting is sticky, meaning that numerous operations can be cascaded and then the flag need only be checked at the end. Whether the operation is signed or unsigned is indicated by an 's' or 'u' suffix, respectively. While this could be achieved without such suffixes by using overloading on the signedness of the types, the suffix makes it clear which is happening without needing to examine the types.
While the generic versions of these functions are computationally expensive relative to the cost of the operation itself, compiler implementations are free to recognize them and generate equivalent and faster code.
The functions here are templates so they can be used with -betterC, as betterC does not link with this library.

References Fast Integer Overflow Checks

License:
Boost License 1.0
Authors:
Walter Bright

Source core/checkedint.d

int `adds`()(int `x`, int `y`, ref bool `overflow`);
long `adds`()(long `x`, long `y`, ref bool `overflow`);
  Add two signed integers, checking for overflow.
  The overflow is sticky, meaning a sequence of operations can be done and overflow need only be checked at the end.
  Parameters:

  int `x` | left operand
  int `y` | right operand
  bool `overflow` | set if an overflow occurs, is not affected otherwise

  Returns:
  the sum
  Examples:

      bool overflow;
      assert(adds(2, 3, overflow) == 5);
      assert(!overflow);

      assert(adds(1, int.max - 1, overflow) == int.max);
      assert(!overflow);

      assert(adds(int.min + 1, -1, overflow) == int.min);
      assert(!overflow);

      assert(adds(int.max, 1, overflow) == int.min);
      assert(overflow);

      overflow = false;
      assert(adds(int.min, -1, overflow) == int.max);
      assert(overflow);

      assert(adds(0, 0, overflow) == 0);
      assert(overflow);                   // sticky

  Examples:

      bool overflow;
      assert(adds(2L, 3L, overflow) == 5);
      assert(!overflow);

      assert(adds(1L, long.max - 1, overflow) == long.max);
      assert(!overflow);

      assert(adds(long.min + 1, -1, overflow) == long.min);
      assert(!overflow);

      assert(adds(long.max, 1, overflow) == long.min);
      assert(overflow);

      overflow = false;
      assert(adds(long.min, -1, overflow) == long.max);
      assert(overflow);

      assert(adds(0L, 0L, overflow) == 0);
      assert(overflow);                   // sticky

uint `addu`()(uint `x`, uint `y`, ref bool `overflow`);
ulong `addu`()(ulong `x`, ulong `y`, ref bool `overflow`);
  Add two unsigned integers, checking for overflow (aka carry).
  The overflow is sticky, meaning a sequence of operations can be done and overflow need only be checked at the end.
  Parameters:

  uint `x` | left operand
  uint `y` | right operand
  bool `overflow` | set if an overflow occurs, is not affected otherwise

  Returns:
  the sum
  Examples:

      for (uint i = 0; i < 10; ++i)
      {
          bool overflow;
          immutable uint r = addu (uint.max - i, uint.max - i, overflow);
          assert (r == 2 * (uint.max - i));
          assert (overflow);
      }

      bool overflow;
      assert(addu(2, 3, overflow) == 5);
      assert(!overflow);

      assert(addu(1, uint.max - 1, overflow) == uint.max);
      assert(!overflow);

      assert(addu(uint.min, -1, overflow) == uint.max);
      assert(!overflow);

      assert(addu(uint.max, 1, overflow) == uint.min);
      assert(overflow);

      overflow = false;
      assert(addu(uint.min + 1, -1, overflow) == uint.min);
      assert(overflow);

      assert(addu(0, 0, overflow) == 0);
      assert(overflow);                   // sticky

  Examples:

      bool overflow;
      assert(addu(2L, 3L, overflow) == 5);
      assert(!overflow);

      assert(addu(1, ulong.max - 1, overflow) == ulong.max);
      assert(!overflow);

      assert(addu(ulong.min, -1L, overflow) == ulong.max);
      assert(!overflow);

      assert(addu(ulong.max, 1, overflow) == ulong.min);
      assert(overflow);

      overflow = false;
      assert(addu(ulong.min + 1, -1L, overflow) == ulong.min);
      assert(overflow);

      assert(addu(0L, 0L, overflow) == 0);
      assert(overflow);                   // sticky

int `subs`()(int `x`, int `y`, ref bool `overflow`);
long `subs`()(long `x`, long `y`, ref bool `overflow`);
  Subtract two signed integers, checking for overflow.
  The overflow is sticky, meaning a sequence of operations can be done and overflow need only be checked at the end.
  Parameters:

  int `x` | left operand
  int `y` | right operand
  bool `overflow` | set if an overflow occurs, is not affected otherwise

  Returns:
  the difference
  Examples:

      bool overflow;
      assert(subs(2, -3, overflow) == 5);
      assert(!overflow);

      assert(subs(1, -int.max + 1, overflow) == int.max);
      assert(!overflow);

      assert(subs(int.min + 1, 1, overflow) == int.min);
      assert(!overflow);

      assert(subs(int.max, -1, overflow) == int.min);
      assert(overflow);

      overflow = false;
      assert(subs(int.min, 1, overflow) == int.max);
      assert(overflow);

      assert(subs(0, 0, overflow) == 0);
      assert(overflow);                   // sticky

  Examples:

      bool overflow;
      assert(subs(2L, -3L, overflow) == 5);
      assert(!overflow);

      assert(subs(1L, -long.max + 1, overflow) == long.max);
      assert(!overflow);

      assert(subs(long.min + 1, 1, overflow) == long.min);
      assert(!overflow);

      assert(subs(-1L, long.min, overflow) == long.max);
      assert(!overflow);

      assert(subs(long.max, -1, overflow) == long.min);
      assert(overflow);

      overflow = false;
      assert(subs(long.min, 1, overflow) == long.max);
      assert(overflow);

      assert(subs(0L, 0L, overflow) == 0);
      assert(overflow);                   // sticky

uint `subu`()(uint `x`, uint `y`, ref bool `overflow`);
ulong `subu`()(ulong `x`, ulong `y`, ref bool `overflow`);
  Subtract two unsigned integers, checking for overflow (aka borrow).
  The overflow is sticky, meaning a sequence of operations can be done and overflow need only be checked at the end.
  Parameters:

  uint `x` | left operand
  uint `y` | right operand
  bool `overflow` | set if an overflow occurs, is not affected otherwise

  Returns:
  the difference
  Examples:

      bool overflow;
      assert(subu(3, 2, overflow) == 1);
      assert(!overflow);

      assert(subu(uint.max, 1, overflow) == uint.max - 1);
      assert(!overflow);

      assert(subu(1, 1, overflow) == uint.min);
      assert(!overflow);

      assert(subu(0, 1, overflow) == uint.max);
      assert(overflow);

      overflow = false;
      assert(subu(uint.max - 1, uint.max, overflow) == uint.max);
      assert(overflow);

      assert(subu(0, 0, overflow) == 0);
      assert(overflow);                   // sticky

  Examples:

      bool overflow;
      assert(subu(3UL, 2UL, overflow) == 1);
      assert(!overflow);

      assert(subu(ulong.max, 1, overflow) == ulong.max - 1);
      assert(!overflow);

      assert(subu(1UL, 1UL, overflow) == ulong.min);
      assert(!overflow);

      assert(subu(0UL, 1UL, overflow) == ulong.max);
      assert(overflow);

      overflow = false;
      assert(subu(ulong.max - 1, ulong.max, overflow) == ulong.max);
      assert(overflow);

      assert(subu(0UL, 0UL, overflow) == 0);
      assert(overflow);                   // sticky

int `negs`()(int `x`, ref bool `overflow`);
long `negs`()(long `x`, ref bool `overflow`);
  Negate an integer.
  Parameters:

  int `x` | operand
  bool `overflow` | set if x cannot be negated, is not affected otherwise

  Returns:
  the negation of x
  Examples:

      bool overflow;
      assert(negs(0, overflow) == -0);
      assert(!overflow);

      assert(negs(1234, overflow) == -1234);
      assert(!overflow);

      assert(negs(-5678, overflow) == 5678);
      assert(!overflow);

      assert(negs(int.min, overflow) == -int.min);
      assert(overflow);

      assert(negs(0, overflow) == -0);
      assert(overflow);                   // sticky

  Examples:

      bool overflow;
      assert(negs(0L, overflow) == -0);
      assert(!overflow);

      assert(negs(1234L, overflow) == -1234);
      assert(!overflow);

      assert(negs(-5678L, overflow) == 5678);
      assert(!overflow);

      assert(negs(long.min, overflow) == -long.min);
      assert(overflow);

      assert(negs(0L, overflow) == -0);
      assert(overflow);                   // sticky

int `muls`()(int `x`, int `y`, ref bool `overflow`);
long `muls`()(long `x`, long `y`, ref bool `overflow`);
  Multiply two signed integers, checking for overflow.
  The overflow is sticky, meaning a sequence of operations can be done and overflow need only be checked at the end.
  Parameters:

  int `x` | left operand
  int `y` | right operand
  bool `overflow` | set if an overflow occurs, is not affected otherwise

  Returns:
  the product
  Examples:

      bool overflow;
      assert(muls(2, 3, overflow) == 6);
      assert(!overflow);

      assert(muls(-200, 300, overflow) == -60_000);
      assert(!overflow);

      assert(muls(1, int.max, overflow) == int.max);
      assert(!overflow);

      assert(muls(int.min, 1, overflow) == int.min);
      assert(!overflow);

      assert(muls(int.max, 2, overflow) == (int.max * 2));
      assert(overflow);

      overflow = false;
      assert(muls(int.min, -1, overflow) == int.min);
      assert(overflow);

      assert(muls(0, 0, overflow) == 0);
      assert(overflow);                   // sticky

  Examples:

      bool overflow;
      assert(muls(2L, 3L, overflow) == 6);
      assert(!overflow);

      assert(muls(-200L, 300L, overflow) == -60_000);
      assert(!overflow);

      assert(muls(1, long.max, overflow) == long.max);
      assert(!overflow);

      assert(muls(long.min, 1L, overflow) == long.min);
      assert(!overflow);

      assert(muls(long.max, 2L, overflow) == (long.max * 2));
      assert(overflow);
      overflow = false;

      assert(muls(-1L, long.min, overflow) == long.min);
      assert(overflow);

      overflow = false;
      assert(muls(long.min, -1L, overflow) == long.min);
      assert(overflow);

      assert(muls(0L, 0L, overflow) == 0);
      assert(overflow);                   // sticky

uint `mulu`()(uint `x`, uint `y`, ref bool `overflow`);
ulong `mulu`()(ulong `x`, uint `y`, ref bool `overflow`);
ulong `mulu`()(ulong `x`, ulong `y`, ref bool `overflow`);
  Multiply two unsigned integers, checking for overflow (aka carry).
  The overflow is sticky, meaning a sequence of operations can be done and overflow need only be checked at the end.
  Parameters:

  uint `x` | left operand
  uint `y` | right operand
  bool `overflow` | set if an overflow occurs, is not affected otherwise

  Returns:
  the product

Copyright © 1999-2023 by the D Language Foundation | Page generated by Ddoc on Wed Feb 15 22:42:42 2023