Please enable JavaScript to view this site.

ASQL Reference

Navigation: » No topics above this level «

Displaying Two Numeric Values

Scroll Prev Top Next More

A developer writes, January 2024:

Found an interesting display problem the other day. Don't know if it has always been there or has shown up with recent updates. It has to do with displaying the total of two numeric values. We have always been able to create a string using 'string = num using mask'. How ever if you try doing it using 'string = (num1+num2) using mask' what you get in the string is the correct digits but the number has been multiplied by 10. In order to get the correct string value you now need to use 'string = STR(num1+num2) using mask'. I have attached a test program that you can use to check it out. This occurs whether the display is whole numbers or has decimal points in it. I first thought it had to do with the mask that was being used but finally found that you need to use the STR() format now. Is the STR required or is there a problem with the conversion using the (num1+num2) format? If STR() format is required I think the compiler should be giving you some sort of error message.

MicroSabio Reponds

Thanks for the interesting observation. I'm not sure if this problem has always been in AlphaBASIC, as I no longer have access to a working AMOS box. But I think there is a reasonably good chance that it has always been there as a consequence of the combination of two somewhat unique features/curses of AlphaBASIC:

The + operator acts as either addition or concatenation, depending on the data type of the arguments
Numbers get automatically converted to strings, and vice versa, based on rules which aren't always intuitively obvious.

The second point uses a rule that sounds simple but quickly gets confusing: basically it says that the first token (variable or literal) in a statement sets the mode for that statement to either numeric or string. Then as we proceed left to right across the statement, the mode causes conversion of strings to numbers or vice versa, and that then affects the interpretation of the + operator. But, the current mode changes in response to certain functions or operators that demand a particular mode. Division, for example, demands numeric mode, so it will auto-convert strings to the right of the / operator into numbers. The STR(x) function 'demands' that x be numeric so that it can be converted to string. So if x is a string, it first gets converted to a number, and then it gets converted to a string by the STR() function, which also causes the mode of the statement to change to string. That's kind of redundant/meaningless with for STR(x), but it becomes significant with STR(x+y), since converting x and y to numbers forces the + to be addition.

So what's happening in your example is concatenation rather than addition; not some kind 10X factor. Essentially you have something equivalent to:

((164408 + 0)/100) using mask

which would result in 1,644.80 as expected. But if you assign the output to a string variable, i.e:

string$ = ((164408 + 0)/100) using mask

then the mysterious auto-conversion rules kick in. Since string$ is a string variable, the compiler switches the mode from numeric to string, which causes the arguments to the right of the equals sign to be converted to strings. The 0 is getting appended, resulting in 1644080, which then becomes 16440.80 when divided by 100. So it essentially becomes:

string$ = ((str(164408) + str(0))/100) using mask

Your workaround of using STR around the (num1+num2) overrides that, somewhat paradoxically, because the STR() function expects numeric arguments. So it treats the num1 + num2 as a numeric addition.

I'll admit that it seems pretty screwy, but I didn't invent that logic. And unfortunately there is no global switch to disable this mode-conversion logic and force + to act as addition. However, A-Shell does have a pair of Explicit Plus Operators, (#+ for addition and $+ for concatenation) that can be used as one way of short-circuiting this problem. That is, you could use 'string = (num1 #+ num2) using mask' to force addition instead of concatenation.

Another alternative is to use an intermediate numeric value to receive the result of those addition operations before plugging them into the string PLINE, i.e. 'tempnum = (num1 + num2) using mask'.

This is probably the one quirk in AlphaBASIC that causes the most problems, and virtually always it's in a situation like this where you stumble on it unexpectedly after writing thousands of programs! Don't feel bad; I'm confident it has happened to everyone, some of whom may just not realize it yet.