Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Overflow check on integer multiplication in C ?

Overflow check on integer multiplication in C ?

Scheduled Pinned Locked Moved C / C++ / MFC
tutorialcsshelpquestion
5 Posts 5 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Offline
    H Offline
    Hans999
    wrote on last edited by
    #1

    Hello, I need to multiply integer value with a factor and want to do an overflow check with INT_MAX, INT_MIN for this. Integer contains 4 bytes on my machine an this is the max variable-size. I need to do this check for signed integer and unsigned integer. Only integer math/variables allowed. The factor always comes as fraction with a nominator and denominator. The denominator always is 10 Factor might be greater 1 or less than 1

    So for example fraction is 25/10, varible a is signed integer

    a = (a * 25)/10 -> may cause overflow, because (a * 25) can be > INT_MAX ( or < INT_MIN )

    Overflow checks:
    if (a > (INT_MAX * 10)/25 -> not possible because of overflow, INT_MAX is the maximum number the compiler can store.
    if (a > INT_MAX * (10/25) -> not possible because 10/25 is 0.4 which will be 0 in integer math.

    So any idea how to solve my problem?

    Thanks for any hint!

    D J L 3 Replies Last reply
    0
    • H Hans999

      Hello, I need to multiply integer value with a factor and want to do an overflow check with INT_MAX, INT_MIN for this. Integer contains 4 bytes on my machine an this is the max variable-size. I need to do this check for signed integer and unsigned integer. Only integer math/variables allowed. The factor always comes as fraction with a nominator and denominator. The denominator always is 10 Factor might be greater 1 or less than 1

      So for example fraction is 25/10, varible a is signed integer

      a = (a * 25)/10 -> may cause overflow, because (a * 25) can be > INT_MAX ( or < INT_MIN )

      Overflow checks:
      if (a > (INT_MAX * 10)/25 -> not possible because of overflow, INT_MAX is the maximum number the compiler can store.
      if (a > INT_MAX * (10/25) -> not possible because 10/25 is 0.4 which will be 0 in integer math.

      So any idea how to solve my problem?

      Thanks for any hint!

      D Offline
      D Offline
      Daniel Pfeffer
      wrote on last edited by
      #2

      One way would be to perform the multiplication as a double-precision operation, and then examine the high word. For unsigned values (in pseudocode):

      // HI_HALF - returns the upper N/2 bits of an N-bit integer
      // LO_HALF - returns the lower N/2 bits of an N-bit integer
      // MAKE_DIGIT - combines two N/2-bit values to make an N-bit integer

      // multiply a DIGIT a by a DIGIT b, returning a two-DIGIT result
      // a, b must be unsigned

      DIGIT alow = LO_HALF(a)
      DIGIT ahigh = HI_HALF(a)
      DIGIT blow = LO_HALF(b)
      DIGIT bhigh = HI_HALF(b)
      DIGIT carry
      DIGIT accumulator
      DIGIT result[4]

      accumulator = alow * blow
      carry = HI_HALF(accumulator)
      result[0] = LO_HALF(accumulator)

      accumulator = alow * bhigh + carry
      result[1] = LO_HALF(accumulator)
      result[2] = HI_HALF(accumulator)

      accumulator = ahigh * blow + result[1]
      result[1] = LO_HALF(accumulator)
      carry = HI_HALF(accumulator)

      accumulator = ahigh * bhigh + result[2] + carry
      result[2] = LO_HALF(accumulator)
      result[3] = HI_HALF(accumulator)

      // combine result[3] and result[2] into 1 DIGIT
      // combine result[1] and result[0] into 1 DIGIT
      return MAKE_DIGIT(result[3], result[2]), MAKE_DIGIT(result[1], result[0])

      Note that many optimizations may be performed on the above code; it is laid out like this for easy comprehension. For the operation a * b, if the high digit is non-zero, the result has overflowed For the operation a * b / c, if the high DIGIT of (a * b) >= c, then the entire operation will overflow. Signed values are left as an exercise for the student.

      Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.

      1 Reply Last reply
      0
      • H Hans999

        Hello, I need to multiply integer value with a factor and want to do an overflow check with INT_MAX, INT_MIN for this. Integer contains 4 bytes on my machine an this is the max variable-size. I need to do this check for signed integer and unsigned integer. Only integer math/variables allowed. The factor always comes as fraction with a nominator and denominator. The denominator always is 10 Factor might be greater 1 or less than 1

        So for example fraction is 25/10, varible a is signed integer

        a = (a * 25)/10 -> may cause overflow, because (a * 25) can be > INT_MAX ( or < INT_MIN )

        Overflow checks:
        if (a > (INT_MAX * 10)/25 -> not possible because of overflow, INT_MAX is the maximum number the compiler can store.
        if (a > INT_MAX * (10/25) -> not possible because 10/25 is 0.4 which will be 0 in integer math.

        So any idea how to solve my problem?

        Thanks for any hint!

        J Offline
        J Offline
        Joe Woodbury
        wrote on last edited by
        #3

        All that matters is if a * factor overflows, so the /10 can be ignored. I believe you just need to check if (a <= (INTMAX / factor)).

        1 Reply Last reply
        0
        • H Hans999

          Hello, I need to multiply integer value with a factor and want to do an overflow check with INT_MAX, INT_MIN for this. Integer contains 4 bytes on my machine an this is the max variable-size. I need to do this check for signed integer and unsigned integer. Only integer math/variables allowed. The factor always comes as fraction with a nominator and denominator. The denominator always is 10 Factor might be greater 1 or less than 1

          So for example fraction is 25/10, varible a is signed integer

          a = (a * 25)/10 -> may cause overflow, because (a * 25) can be > INT_MAX ( or < INT_MIN )

          Overflow checks:
          if (a > (INT_MAX * 10)/25 -> not possible because of overflow, INT_MAX is the maximum number the compiler can store.
          if (a > INT_MAX * (10/25) -> not possible because 10/25 is 0.4 which will be 0 in integer math.

          So any idea how to solve my problem?

          Thanks for any hint!

          L Offline
          L Offline
          leon de boer
          wrote on last edited by
          #4

          It will take more effort and cpu cycles to pick off the overflow than simply move it to next size up integer, do the mult on a that type and look at the result for overflow So for 16 bit int and 32bit long as an example

          long b = a;
          b *=25
          b /=10
          if (b & 0x7FFF0000 != 0)
          {
          // error result in b is larger than an int
          }
          a = (int) b;

          If you want to do it proper anal uses standard ints

          #include
          int16_t a = ????;
          int32_t b = a;
          b *=25
          b /=10
          if (b & 0x7FFF0000 != 0)
          {
          // error result in b is larger than an int
          }
          a = (int16_t) b;

          In vino veritas

          CPalliniC 1 Reply Last reply
          0
          • L leon de boer

            It will take more effort and cpu cycles to pick off the overflow than simply move it to next size up integer, do the mult on a that type and look at the result for overflow So for 16 bit int and 32bit long as an example

            long b = a;
            b *=25
            b /=10
            if (b & 0x7FFF0000 != 0)
            {
            // error result in b is larger than an int
            }
            a = (int) b;

            If you want to do it proper anal uses standard ints

            #include
            int16_t a = ????;
            int32_t b = a;
            b *=25
            b /=10
            if (b & 0x7FFF0000 != 0)
            {
            // error result in b is larger than an int
            }
            a = (int16_t) b;

            In vino veritas

            CPalliniC Offline
            CPalliniC Offline
            CPallini
            wrote on last edited by
            #5

            Nice. :thumbsup:

            In testa che avete, signor di Ceprano?

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups