• You've discovered RedGuides 📕 an EverQuest multi-boxing community 🛡️🧙🗡️. We want you to play several EQ characters at once, come join us and say hello! 👋
  • IS THIS SITE UGLY? Change the look. To dismiss this notice, click the X --->

Request - Easier way to code numeric comma replacement? (1 Viewer)

Joined
Sep 12, 2004
RedCents
60¢
If anyone can figure out a simpler way to do this, I welcome the input.

Taking an integer value, and displaying it as a string value to show comma placement for thousands.

Turn DebugComma on (1) to see the step by step logic behind it when running.

Comma.mac

Rich (BB code):
#turbo

|-------------------------------------------------------------------------------- 
|SUB: Main
|--------------------------------------------------------------------------------
Sub Main

|------------------------------------
| Required declarations.
|------------------------------------
/declare  ValTotal int outer 1987123574
/declare  ValTotalStr  string outer    
|------------------------------------

/call ValTotComma ${ValTotal}
/echo Final ValTotalStr=(${ValTotalStr})

/return
|-------------------------------------------------------------------------------- 

|-------------------------------------------------------------------------------- 
|SUB: ValTotComma(string ValTotalStrTmp)
|--------------------------------------------------------------------------------
Sub ValTotComma(string ValTotalStrTmp)

/declare i              int    local
/declare DebugComma     int    local  0

/if (${DebugComma}) /echo ValTotalLen=(${ValTotalLen}) ValTotalStrTmp=(${ValTotalStrTmp})

/if (${Int[${ValTotalStrTmp.Length}]}>3) {
    /for i 1 to 4
        /declare ValTotalStrP${i}  string   local
        /if (${DebugComma}) /echo ValTotalStrTmp=(${ValTotalStrTmp}) ++    
        /if (${Int[${ValTotalStrTmp.Length}]}>=3) {        	
	    /varset ValTotalStrP${i} ${ValTotalStrTmp.Right[3]}
	    /if (${DebugComma}) /echo ValTotalStrP${i}=(${ValTotalStrP${i}}) -	
	    /varset ValTotalStrTmp ${ValTotalStrTmp.Left[-3]}			    	    
	    /if (${DebugComma}) /echo ValTotalStrTmp.Length=(${ValTotalStrTmp.Length})	    
	    /if (${i}>1) {
	        /varset ValTotalStr ${ValTotalStrP${i}},${ValTotalStr}
	    } else {
	        /varset ValTotalStr ${ValTotalStrP${i}}${ValTotalStr}
	    }	    
	    /if (${DebugComma}) /echo ValTotalStr=(${ValTotalStr})	
        } else /if (${ValTotalStrTmp.Length}) {
            /varset ValTotalStrP${i} ${ValTotalStrTmp.Right[3]}
            /if (${DebugComma}) /echo ValTotalStrP${i}=(${ValTotalStrP${i}}) --
            /varset ValTotalStr ${ValTotalStrP${i}},${ValTotalStr}       
            /varset ValTotalStrTmp
            /if (${DebugComma}) /echo ValTotalStr=(${ValTotalStr})
        }    
    /next i                
} else {
    /varset ValTotalStr ${ValTotalStrTmp}
}
       
/return
|--------------------------------------------------------------------------------
 
Last edited:
I approached this from another direction:

Rich (BB code):
#turbo

|-------------------------------------------------------------------------------- 
|SUB: Main
|--------------------------------------------------------------------------------
Sub Main

|------------------------------------
| Required declarations.
|------------------------------------
/declare  ValTotal int outer 1111999
/declare  ValTotalStr  string outer    
|------------------------------------

/call ValTotComma ${ValTotal}
/echo Final ValTotalStr=${ValTotalStr}

/return
|-------------------------------------------------------------------------------- 

|-------------------------------------------------------------------------------- 
|SUB: ValTotComma(int intValToConvert)
|--------------------------------------------------------------------------------
Sub ValTotComma(int intValToConvert)

/declare DebugComma bool local true

| Handle the trivial case of no commas needed, does not handle negative numbers

/if (${intValToConvert} < 1000) {
	/if (${DebugComma}) /echo No commas if value is < 1000
	/varset ValTotalStr ${intValToConvert}
	/return
}

| We'll be altering the value of what we are converting so declare a local variable
/declare num int local ${intValToConvert}
/if (${DebugComma}) /echo Converting: ${num}

| If we got here, we are converting a number that needs commas added
| We are finding the values using mod's

/declare modNum int local 1000
/declare rem int local

| Loop while the number is > 0

:LOOPSTART	

        | $rem is the number % 1000 --- So, if 111,364 == $num, $rem = 364

	/varset rem ${Math.Calc[${num}%${modNum}]}
	/if (${DebugComma}) /echo Remainder: ${rem}
	
        | Add $rem to the front end of the string being modified

	/varset ValTotalStr ${rem}${ValTotalStr}
	/if (${DebugComma}) /echo Current String: ${ValTotalStr}

        | Divide num by 1000 --- This is int division, so if 111,364 == $num, $num becomes 111

	/varcalc num ${num}/${modNum}
	/if (${DebugComma}) /echo num is now ${num}
	
        | $num will only be zero when we are done, so we add the comma to the front end of the 
        | string being converted and start the loop again with the new value of $num

	/if (${num}>0) { 
		/varset ValTotalStr ,${ValTotalStr}
		/goto :LOOPSTART
	}
/return
|--------------------------------------------------------------------------------

There are probably bugs, but that's the approach I would take.


And a recursive solution, inspired by PussyFoot:
Rich (BB code):
#turbo

|-------------------------------------------------------------------------------- 
|SUB: Main
|--------------------------------------------------------------------------------
Sub Main

|------------------------------------
| Required declarations.
|------------------------------------
/declare  ValTotal int outer 1000999
/declare  ValTotalStr  string outer    
|------------------------------------

/call ValTotComma ${ValTotal}
/echo Final ValTotalStr=${ValTotalStr}

/return
|-------------------------------------------------------------------------------- 

|-------------------------------------------------------------------------------- 
|SUB: ValTotComma(int intValToConvert)
|--------------------------------------------------------------------------------
Sub ValTotComma(string remaining)

| Base case - remaining length <= 3
/if (${remaining.Length}<=3) {
    /varset ValTotalStr ${remaining}${ValTotalStr}
    /echo ValTotalStr = ${ValTotalStr} base case
    /return
}
/varset ValTotalStr ,${remaining.Right[3]}${ValTotalStr}
/echo ValTotalStr = ${ValTotalStr} not base case
/call ValTotComma ${remaining.Left[-3]}
/return
|--------------------------------------------------------------------------------

With this code, I get the following output:
Rich (BB code):
ValTotalStr = ,999 not base case
ValTotalStr = ,000,999 not base case
ValTotalStr = 1,000,999 base case
Final ValTotalStr=1,000,999
 
Last edited:
Interesting, I would never have thought to take that logical path to the solution you did... cool.

Thanks for taking a stab at it. I always like to get other peoples coding ideas.. lord knows there is more than one way to code just about anything... the right.. the wrong.. the efficient.. etc.. lol
 
No prob. On the other side I love coding puzzles. Bring em on!

- - - Updated - - -

Thought of a bug. For 1,000,000 this would probably output 1,0,0. To get around that:

Rich (BB code):
| Add $rem to the front end of the string being modified

/varset ValTotalStr ${rem}${ValTotalStr}
/if (${DebugComma}) /echo Current String: ${ValTotalStr}

| Divide num by 1000 --- This is int division, so if 111,364 == $num, $num becomes 111

should become

Rich (BB code):
| Add $rem to the front end of the string being modified

/varset ValTotalStr ${rem}${ValTotalStr}
/if (${rem}<100) /varset ValTotalStr 0${ValTotalStr}
/if (${rem}<10) /varset ValTotalStr 0${ValTotalStr}
/if (${rem}==0) /varset ValTotalStr 0${ValTotalStr}
/if (${DebugComma}) /echo Current String: ${ValTotalStr}

| Divide num by 1000 --- This is int division, so if 111,364 == $num, $num becomes 111

That might work, but haven't tried it.
 
If rem were a string you could just do this.


Rich (BB code):
| Add $rem to the front end of the string being modified

/if (${rem.Length}<3) {
   /varset rem 000${rem)
   /varset rem ${rem.Right[3]}
}
/varset ValTotalStr ${rem}${ValTotalStr}
/if (${DebugComma}) /echo Current String: ${ValTotalStr}

| Divide num by 1000 --- This is int division, so if 111,364 == $num, $num becomes 111
 
Can you do self calling functions? Never tried in macroquest, but could you do

Sub Convert(int valuetoconvert)
{
/if statements to see if it's < 3
/if not less than 3 do function to add values and subtract those 3 spaces
/call Convert(valuetoconvert)
}

Dunno if it allows that sort of iteration though, would make it very efficient if it did. Sometimes I wish we could code directly in C++
 
Can you do self calling functions? Never tried in macroquest, but could you do

Sub Convert(int valuetoconvert)
{
/if statements to see if it's < 3
/if not less than 3 do function to add values and subtract those 3 spaces
/call Convert(valuetoconvert)
}

Dunno if it allows that sort of iteration though, would make it very efficient if it did. Sometimes I wish we could code directly in C++

Ooh, recursion in macroquest macros. I hadn't even considered that. I might have to play with that some.

So I played with it some... Updated my first post with a recursive solution.

- - - Updated - - -

If rem were a string you could just do this.


Rich (BB code):
| Add $rem to the front end of the string being modified

/if (${rem.Length}<3) {
   /varset rem 000${rem)
   /varset rem ${rem.Right[3]}
}
/varset ValTotalStr ${rem}${ValTotalStr}
/if (${DebugComma}) /echo Current String: ${ValTotalStr}

| Divide num by 1000 --- This is int division, so if 111,364 == $num, $num becomes 111

That's interesting. In fact, that fix would work even if rem.Length == 3.
If I'm thinking right.

rem == 312 -> 000312 -> rem.Right[3] == 312.

Sure, it's unnecessary, but it lets you get away with not doing a string conversion.

That would always work wouldn't it? Until the final section. 1234567 -> 001,234,567 as it currently stands if I'm following it right.
 
Last edited:
Exactly.. Would only have to check for last loop not to add the leading zeros.

This Has not been tested, but this is how I would of approached it.

Rich (BB code):
#turbo

|-------------------------------------------------------------------------------- 
|SUB: Main
|--------------------------------------------------------------------------------
Sub Main

|------------------------------------
| Required declarations.
|------------------------------------
/declare  ValTotal int outer 1987123574
/declare  ValTotalStr  string outer    
|------------------------------------

/call ValTotComma ${ValTotal}
/echo Final ValTotalStr=(${ValTotalStr})

/return
|-------------------------------------------------------------------------------- 

|-------------------------------------------------------------------------------- 
|SUB: ValTotComma(string ValTotalStrTmp)
|--------------------------------------------------------------------------------
Sub ValTotComma(string ValTotalStrTmp)

/declare i              int    local
/declare DebugComma     int    local  0
/declare StrWithCommas  string local

/if (${DebugComma}) /echo ValTotalLen=(${ValTotalLen}) ValTotalStrTmp=(${ValTotalStrTmp})

/if (${Int[${ValTotalStrTmp.Length}]}>3) {
    /for i ${ValTotalStrTmp.Length}]} downto 1 step -3
       /if (${i}>3) { 
          /varset StrWithCommas ,${ValTotalStrTmp.Mid[${Math.Calc[(${i}-2)]},3]}${StrWithCommas}
       } else {
          /varset StrWithCommas ${ValTotalStrTmp.Left[${i}]}${StrWithCommas}
       }
    /next i                
    /varset ValTotalStr ${StrWithCommas}
} else {
    /varset ValTotalStr ${ValTotalStrTmp}
}
       
/return
|--------------------------------------------------------------------------------

This would have to be tweaked a bit to make sure that ${i} is landing on the correct position in ${ValTotalStrTmp). Then you wouldn't have to worry about padding with zeros.
 
CommaNation Domination

For CommaNating Dominating up to 12 digits

Rich (BB code):
| CommaNator Dominator Macro
| comma.mac v1.0 Maskoi 002/17/2015

Sub Main
    /call CommaMeBro 123
    /echo ${Macro.Return}

    /call CommaMeBro 1234
    /echo ${Macro.Return}

    /call CommaMeBro 123456
    /echo ${Macro.Return}

    /call CommaMeBro 1234567
    /echo ${Macro.Return}

    /call CommaMeBro 123456789
    /echo ${Macro.Return}

    /call CommaMeBro 123456789123
    /echo ${Macro.Return}
/return

    Sub CommaMeBro(string cmbnumber)
        /declare CommaNator string local 
        | Strip out any decimal points 
        /varset cmbnumber ${cmbnumber.Arg[1,.]}
        /if (${cmbnumber.Length}<=3 ) /varset CommaNator ${cmbnumber}
        /if (${cmbnumber.Length}>3 && ${cmbnumber.Length}<=6) /varset CommaNator  ${cmbnumber.Left[${Math.Calc[${cmbnumber.Length}-3]}]},${cmbnumber.Right[3]}
        /if (${cmbnumber.Length}>6  && ${cmbnumber.Length}<=9) /varset CommaNator ${cmbnumber.Left[${Math.Calc[${cmbnumber.Length}-6]}]},${cmbnumber.Mid[${Math.Calc[${cmbnumber.Length}-5]},3]},${cmbnumber.Right[3]}
        /if (${cmbnumber.Length}>9) /varset CommaNator ${cmbnumber.Left[${Math.Calc[${cmbnumber.Length}-9]}]},${cmbnumber.Mid[${Math.Calc[${cmbnumber.Length}-8]},3]},${cmbnumber.Mid[${Math.Calc[${cmbnumber.Length}-5]},3]},${cmbnumber.Right[3]}
    /return ${CommaNator}

Rich (BB code):
[MQ2] 123
[MQ2] 1,234
[MQ2] 123,456
[MQ2] 1,234,567
[MQ2] 123,456,789
[MQ2] 123,456,789,123
 
Last edited:
Request - Easier way to code numeric comma replacement?

Users who are viewing this thread

Back
Top