Integer overflow traps
Author Message
Integer overflow traps

I haven't used the long integer format much in QB or QBX and
assumed that if a long integer variable or numeric constant appeared
anywhere in an expression that the entire expression would be evaluated
using the long format.  Boy is that wrong.  The expression is parsed, and
at each step, regular integer format is assumed until a long integer
variable or or constant is encountered, at which point, parsing
continues in long integer format.

Example: suppose i% = 20000 and j% = 20000, then

k& = i% + j%      causes an overflow,
k& = 1&*i% + j%   does not cause an overflow,
k& = 1&*(i% + j%) causes an overflow.

Is there a simple and elegant way to force an expression to be
evaluated in long integer format without an intimate knowledge
of the way QB and QBX parse expressions?  A clunky way would be to
multiply each variable or constant by 1&.

Mike

Fri, 08 Jan 1999 03:00:00 GMT
Integer overflow traps

Quote:

> I haven't used the long integer format much in QB or QBX and
> assumed that if a long integer variable or numeric constant appeared
> anywhere in an expression that the entire expression would be evaluated
> using the long format.  Boy is that wrong.  The expression is parsed, and
> at each step, regular integer format is assumed until a long integer
> variable or or constant is encountered, at which point, parsing
> continues in long integer format.

> Example: suppose i% = 20000 and j% = 20000, then

> k& = i% + j%      causes an overflow,
> k& = 1&*i% + j%   does not cause an overflow,
> k& = 1&*(i% + j%) causes an overflow.

> Is there a simple and elegant way to force an expression to be
> evaluated in long integer format without an intimate knowledge
> of the way QB and QBX parse expressions?  A clunky way would be to
> multiply each variable or constant by 1&.

> Mike

This is all from memory and real accurate, BUT the principle is perfect,
I have commercial pgms which use it.
Check out the def.. stuff as in defdbl A.  Then define all variable in
the expression starting with the letter ie
a.pay = a.rate * a.hrs will all be dbl and you do not need to worry how
system evaluates.

You can tell it has bugs, because it's a program.

Fri, 08 Jan 1999 03:00:00 GMT
Integer overflow traps

Quote:

> Is there a simple and elegant way to force an expression to be
> evaluated in long integer format without an intimate knowledge
> of the way QB and QBX parse expressions?  A clunky way would be to
> multiply each variable or constant by 1&.

Why not use CLNG()?  That's what it's for.  Since a function call has
higher precedence than any operator, all you need to do is put it inside
the innermost parentheses, and then all the integers in the expression
will be cast to long prior to evaluation.

---
Glen Blankenship                           Hudsucker Industries

Sat, 09 Jan 1999 03:00:00 GMT
Integer overflow traps

: > Is there a simple and elegant way to force an expression to be
: > evaluated in long integer format without an intimate knowledge
: > of the way QB and QBX parse expressions?  A clunky way would be to
: > multiply each variable or constant by 1&.
:
: Why not use CLNG()?  That's what it's for.  Since a function call has
: higher precedence than any operator, all you need to do is put it inside
: the innermost parentheses, and then all the integers in the expression
: will be cast to long prior to evaluation.
:
: ---

Nope; won't work.  CLNG() is used to round real numerics to long integers.
i%=20000
j%=20000
k&=CLNG(i% + j%)
will produce an overflow error.

Sat, 09 Jan 1999 03:00:00 GMT
Integer overflow traps

: >
[some stuff deleted]
: >
: > Is there a simple and elegant way to force an expression to be
: > evaluated in long integer format without an intimate knowledge
: > of the way QB and QBX parse expressions?  A clunky way would be to
: > multiply each variable or constant by 1&.
: >
: > Mike
:
:
: This is all from memory and real accurate, BUT the principle is perfect,
: I have commercial pgms which use it.
: Check out the def.. stuff as in defdbl A.  Then define all variable in
: the expression starting with the letter ie
: a.pay = a.rate * a.hrs will all be dbl and you do not need to worry how
: system evaluates.
:

: You can tell it has bugs, because it's a program.
This will work for the variables but is not as simple and elegant as I
would like.  It will bomb though if you aren't careful with numeric
constants (e.g. a.pay = a.rate * a.hrs + 200 * 200 will bomb).

Sat, 09 Jan 1999 03:00:00 GMT
Integer overflow traps

Quote:

> : >
> [some stuff deleted]
> : >
> : > Is there a simple and elegant way to force an expression to be
> : > evaluated in long integer format without an intimate knowledge
> : > of the way QB and QBX parse expressions?  A clunky way would be to
> : > multiply each variable or constant by 1&.
> : >
> : > Mike
> :
> :
> : This is all from memory and real accurate, BUT the principle is perfect,
> : I have commercial pgms which use it.
> : Check out the def.. stuff as in defdbl A.  Then define all variable in
> : the expression starting with the letter ie
> : a.pay = a.rate * a.hrs will all be dbl and you do not need to worry how
> : system evaluates.
> :

> : You can tell it has bugs, because it's a program.
> This will work for the variables but is not as simple and elegant as I
> would like.  It will bomb though if you aren't careful with numeric
> constants (e.g. a.pay = a.rate * a.hrs + 200 * 200 will bomb).

You can either set a200=200 first and use a200 in the formula or stick
the proper modifier on the end of the 200s  ie 200# (or whatever).

Also, be aware that sometimes the stuff works (or does not work) in the
enviornment (sp?) and does the opposite when compiled!

Sat, 09 Jan 1999 03:00:00 GMT
Integer overflow traps

: > Nope; won't work.  CLNG() is used to round real numerics to long integers.
: > i%=20000
: > j%=20000
: > k&=CLNG(i% + j%)
: > will produce an overflow error.
:
: Well, of course it will.  Try doing the conversion *before* you add the
: two numbers, not *after*:
:
: k& = CLNG(i%) + j%
:
: ...or:
:
: k& = i% + CLNG(j%)
:
: ...or even:
:
: k& = CLNG(i%) + CLNG(j%)
:
: All of those will produce identical compiled code, since once you've
: converted one of the numbers, Basic will automatically convert all the
: others to match.  That's why I said to use it inside the innermost
: parens.  The conversion will then propagate outward.  In other words,
:
: k& = (A% * (CLNG(X%) + Y%)) - B%
:
: ...is equivalent to:
:
: k& = (CLNG(A%) * (CLNG(X%) + CLNG(Y%))) - CLNG(B%)
:
: CLNG() can be used to round reals to longs, but it can also be used to
: sign-extend integers to longs.  In OOP-speak it's an "overloaded
: function."  The actual code generated depends on the type of the operand.
:
: If you give it a real number, it calls an internal floating-point library
: function that performs the conversion-and-rounding.  But if you give it an
: integer, it compiles to a simple little snippet of machine code that
: sign-extends the integer to a long.
:
: It works fine, if you use it correctly.
:

Using  CLNG() produces longer source code (but may execute faster) than my
original suggestion of multiplying variables and constants by 1&.

Apparently, the answer to my orignial question of whether there is a
simple or elegant means to force an entire expression to be evaluated in
long integer format without worrying about the internal structure of the
expression is no.  Thanks to those who have replied.

Mike

Sun, 10 Jan 1999 03:00:00 GMT
Integer overflow traps

Quote:

> Nope; won't work.  CLNG() is used to round real numerics to long integers.
> i%=20000
> j%=20000
> k&=CLNG(i% + j%)
> will produce an overflow error.

Well, of course it will.  Try doing the conversion *before* you add the
two numbers, not *after*:

k& = CLNG(i%) + j%

...or:

k& = i% + CLNG(j%)

...or even:

k& = CLNG(i%) + CLNG(j%)

All of those will produce identical compiled code, since once you've
converted one of the numbers, Basic will automatically convert all the
others to match.  That's why I said to use it inside the innermost
parens.  The conversion will then propagate outward.  In other words,

k& = (A% * (CLNG(X%) + Y%)) - B%

...is equivalent to:

k& = (CLNG(A%) * (CLNG(X%) + CLNG(Y%))) - CLNG(B%)

CLNG() can be used to round reals to longs, but it can also be used to
sign-extend integers to longs.  In OOP-speak it's an "overloaded
function."  The actual code generated depends on the type of the operand.

If you give it a real number, it calls an internal floating-point library
function that performs the conversion-and-rounding.  But if you give it an
integer, it compiles to a simple little snippet of machine code that
sign-extends the integer to a long.

It works fine, if you use it correctly.

---
Glen Blankenship                                Hudsucker Industries

Sun, 10 Jan 1999 03:00:00 GMT
Integer overflow traps

I may be wrong so this will be a question instead of a statement:

Can't you just add & to the end of your constants (which would be shorter
than CLNG())? And it would certainly beat multiplying by 1& when you can
just append & to the constant.

Of course, if you didn't HAVE any constants in the expression, I could
certainly see using CLNG.

--

http://www.sat.net/~unol

Quote:

> > Is there a simple and elegant way to force an expression to be
> > evaluated in long integer format without an intimate knowledge
> > of the way QB and QBX parse expressions?  A clunky way would be to
> > multiply each variable or constant by 1&.

> Why not use CLNG()?  That's what it's for.  Since a function call has
> higher precedence than any operator, all you need to do is put it inside
> the innermost parentheses, and then all the integers in the expression
> will be cast to long prior to evaluation.

Sun, 10 Jan 1999 03:00:00 GMT
Integer overflow traps

Quote:

> Using  CLNG() produces longer source code (but may execute faster) than my
> original suggestion of multiplying variables and constants by 1&.

It will certainly execute faster, since QuickBasic doesn't optimize enough
to notice that you're multiplying by a constant 1, and therefore calls the
runtime library's 32-bit multiplication routine.  CLNG(x%) requires only
two simple (and fast) machine instructions:

MOV AX, x%      ;Load x% into the AX register
CWD             ;Convert Word in AX to Doubleword in DX:AX

If the longer source code really bothers you, you could add 0& instead of
multiplying by 1&.  QB actually optimizes this - it realizes that it
doesn't really have to add zero, just convert to a long integer, so you
get exactly the same code as CLNG().

Of course, then you run into precedence issues, since addition has lower
precedence than a number of other operators.  The only way this could
work without paying *any* attention to precedence is to convert every
integer variable x% into a parenthesized expression of the form (x% + 0&),
and that's hardly short or elegant.

(Not to mention the fact that adding 0& really wants a comment to explain
what you're doing, while CLNG() is pretty much self-explanatory.)

Quote:
> Apparently, the answer to my orignial question of whether there is a
> simple or elegant means to force an entire expression to be evaluated in
> long integer format without worrying about the internal structure of the
> expression is no.

Maybe I'm missing something, but "use CLNG() on any integer inside the
innermost set of parentheses" seems pretty simple to me.

---
Glen Blankenship                                Hudsucker Industries

Sun, 10 Jan 1999 03:00:00 GMT

 Page 1 of 1 [ 10 post ]

Relevant Pages