[Solved] [Math] Divide Integers and Round Up

Level 21
Joined
Mar 16, 2008
Messages
952
I need a way to divide two integers and then round it up. Seems the default is to round down. Seems the built-in Round function only works for "real" numbers.

Anyone know the right way to do this?

Convert the integers to real variables then round then convert back to integer for later use?

GOAL: trying to create a system that will create a rounded up ratio of two different classes of players (knights:kings type players). Then we will use this ratio, rounded up, to dynamically limit team sizes in other triggers.
 
Last edited:
Level 29
Joined
Sep 26, 2009
Messages
2,594
Integers by definition are "whole" numbers. They do not have the concept of fractions. So when you divide two integers, only the "whole" number remains and any fractional part is cut off.
So while it may seem like integers round down numbers automatically, the correct way to think about it is that integers don't have a fractional part at all.

So it is as you have thought: You need to convert those integers into reals, divide them, then round them. You may want to add 0.5 to the result so that you can round numbers up.
 
Level 14
Joined
Jan 10, 2023
Messages
246
The issue of adding 0.5 to a real is that the 0.5 would have to be adaptive depending on the denominator and I don't see how you would do this:
R2I( 3.5/4 ) = 0 just like R2I(3/4) = 0

I would do something like a modulus function:
JASS:
local integer a
local integer n = numerator
local integer d = denominator
set a = n/d
if a*d != n then
    set a = a + 1
endif
 
Level 21
Joined
Mar 16, 2008
Messages
952
Would the adding 0.5 method hold with ratios like 11/4 (2.75)? Would this end up rounding it to 4??? we really just want 11/4 to be rounded to 3. But the integer quotient would just chop off any decimals. hmm. Funny how much I'm struggling with basic arithmetic :grin:

I think I'll just go with the multiple conversions integer -> real -> integer thing like Nichilus suggested.
 
Level 21
Joined
Mar 16, 2008
Messages
952
Ok thank you but hmm wait 5/4 would be a problem then. Wouldn't that round up to = 2?

Going back to what this means for the map is 5 knights and 4 kings, so we would want each king to be able to have 2 knights because with a cap of 1 then 1 knight would be unable to have a king.
 
Level 29
Joined
Sep 26, 2009
Messages
2,594
As I wrote in my earlier post, when you convert a real number to integer, the fractional part gets cut off, effectively rounding the number down.
Doing the +0.5 trick will round the number up if the fraction from division result is >= 0.5 (i.e. with the +0.5 trick, a result of 2.5 will get rounded up, while 2.49 will get rounded down).
If you want to round the number up no matter how big the fractional part is, e.g. 1.01 will round up to 2, then the safest way would be to do something like what Tristronic proposed.
For that purpose, there is already an Integer - Math - Modulo function. Using the 5 knights, 4 kings example, the logic would be:
Code:
let knights = 5;
let kings = 4
set result = knights / kings; //this is integer division, so no fractional part
if mod(knights, kings) > 0
    result += 1
 
Level 21
Joined
Mar 16, 2008
Messages
952
EDIT: disregard! it works. only had one of the variables messed up in the calculate ratio trigger.

hmm ok seems to work except when it's a 1:x ratio then it seems to set the cap at zero. Trying to figure out where it goes wrong. Triggers are a huge mess on this map. I tried to copy relevant segments of triggers below:

  • Set Groups and Ally Start
    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Conditions
    • Actions
      • Player Group - Add Player 1 (Red) to Kings_Group_Var
      • Player Group - Add Player 2 (Blue) to Kings_Group_Var
      • Player Group - Add Player 3 (Teal) to Kings_Group_Var
      • Player Group - Add Player 4 (Purple) to Kings_Group_Var
      • Player Group - Add Player 5 (Yellow) to Knights_Group_Var
      • Player Group - Add Player 6 (Orange) to Knights_Group_Var
      • Player Group - Add Player 7 (Green) to Knights_Group_Var
      • Player Group - Add Player 8 (Pink) to Knights_Group_Var
      • Player Group - Add Player 9 (Gray) to Knights_Group_Var
      • Player Group - Add Player 10 (Light Blue) to Knights_Group_Var
      • Player Group - Add Player 11 (Dark Green) to Knights_Group_Var
      • Player Group - Add Player 12 (Brown) to Knights_Group_Var
      • Player Group - Add Player 17 (Wheat) to Knights_Group_Var
      • Player Group - Add Player 18 (Peach) to Knights_Group_Var
      • Player Group - Add Player 19 (Mint) to Knights_Group_Var
      • Player Group - Add Player 20 (Lavender) to Knights_Group_Var
      • Player Group - Add Player1Red to Group1Red
      • Player Group - Add Player13Red_Forces to Group1Red
      • Player Group - Add Player2Blue to Group2Blue
      • Player Group - Add Player14Blue_Forces to Group2Blue
      • Player Group - Add Player3Teal to Group3Teal
      • Player Group - Add Player15Teal_Forces to Group3Teal
      • Player Group - Add Player4Purp to Group4Purp
      • Player Group - Add Player16Purp_Forces to Group4Purp
  • Knight No Show and Intro Animation
    • Events
      • Time - Elapsed game time is 5.00 seconds
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • (Player 5 (Yellow) slot status) Equal to Is unused
              • (Player 5 (Yellow) slot status) Equal to Has left the game
              • (Player 5 (Yellow) controller) Equal to Computer
        • Then - Actions
          • -------- knight limits --------
          • Player Group - Remove Player 5 (Yellow) from Knights_Group_Var.
          • ...
          • (continues in similar pattern for all knights)
  • Red No Show
    • Events
      • Time - Elapsed game time is 8.00 seconds
    • Conditions
      • (Player 1 (Red) slot status) Equal to Is unused
    • Actions
      • Player Group - Remove Player 1 (Red) from Kings_Group_Var.
      • (continues in similar pattern for all kings)
  • calculate knight cap
    • Events
    • Conditions
    • Actions
      • Set VariableSet limits_current_red = ((Number of players in Group1Red) - 2)
      • Set VariableSet limits_current_blue = ((Number of players in Group2Blue) - 2)
      • Set VariableSet limits_current_teal = ((Number of players in Group3Teal) - 2)
      • Set VariableSet limits_current_purp = ((Number of players in Group4Purp) - 2)
      • Set VariableSet limits_num_knights = (Number of players in Knights_Group_Var)
      • Set VariableSet limits_num_kings = (Number of players in Kings_Group_Var)
      • Set VariableSet limits_max_knights = (limits_num_knights / limits_num_kings)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (limits_max_knights mod limits_num_kings) Greater than 0
        • Then - Actions
          • Set VariableSet limits_max_knights = (limits_max_knights + 1)
        • Else - Actions
      • Game - Display to (All players) the text: (String(limits_max_knights))
      • Game - Display to (All players) the text: (String(limits_max_knights))
 
Last edited:

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,860
What is limit_num_knights equal to in that last trigger?

Because 0 mod ANY NUMBER will always equal 0.

Determine what limit_max_knights is equal and what limit_num_kings is equal to prior to doing your math. Display that in a message so you know what you're dealing with. If the numbers seem off then revisit your triggers which set them up and add more "convert integer to text" messages. Debug everything so you can see what is and isn't happening.

Then literally type the equation into a google search to confirm the math: "0 mod 2"
1722967235176.png
 
Last edited:
Level 21
Joined
Mar 16, 2008
Messages
952
The point of the modulo part was to round up if any remainder exists from the division. So if there is let's say a ratio of 1 knights and 3 kings, that would be 1/3, the integer math would consider that zero, but since a remainder exists then it adds 1, so that way the max knights would be 1 knight per kingdom. Nichilus gave me that idea with the modulo to round.

Seem the problem was I was using the wrong variable in the calculation to figure the ratio between knights:kings. Pretty much a typo.
 
Top