Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

numeric overflow

Status
Not open for further replies.

foxmuldr

Programmer
May 17, 2012
19
US
I have a FPW 2.6 screen that uses a numeric input memory variable (m.acct) with a picture clause '999 9999 999' for an input field.

We've taken the SPR and compiled it in VFP9 and it works fine, except that when the user types in all 10 digits it gives a brief wait window that says "numeric overflow" and then continues on properly without data corruption or issue.

I've tried increasing the picture clause to '9999 9999 999', removing the spaces '9999999999' and removing it completely. Nothing changes it. It always gives that message.

I've discovered that it has to do with (2^31)-1, which is the maximum value to store for 31 bits (0x7fffffff). If it's a value that size or smaller, no message. If you get to anything of 32-bits or larger (0x80000000) it causes the error. This happens only on memory variables.

If you input a table field, it works fine.

Does anybody know why this is? Or how to disable the wait window "numeric overflow" message?

Thanks!

Best regards,
Rick C. Hodgin
 
Is your VFP9 Form textbox where the data is entered coupled directly to a data table field?
Said another way, is the ControlSource for the input textbox a table field?

If so your problem may not be with the Form's input Format (picture clause), but instead with the numeric field size into which the data needs to go (defined in the textbox ControlSource).

Good Luck,
JRB-Bldr
 
Rick,

I use to see this years ago with the early versions of VFP. I've not seen it in 9.0.

Take a look at all the properties of the textbox. There must be something non-standard there, probably inserted by the conversion from the SPR. Try viewing "non-default properties only", and reset to default any properties that you are not sure about.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
I found the cause of it. It has to do with the way VFP9 handles integer values. If the value is (2^31)-1 or less, it works with a 32-bit form. If it's 2^31 or higher, it internally upsizes the storage form associated with the variable.

Here's the workaround fix. Instead of using this in the setup code:
m.acct = 0

I need to use this:
m.acct = 0 + (9999999999 - 9999999999)

Which can also be:
#define bignum = 9999999999
m.acct = 0 + (bignum - bignum)

And then m.acct is upsized internally to the larger storage form, even though it still contains the 0 value.

In addition, if you SCATTER MEMVAR from a table, it works, even if the value in the table row is 0 for that field. Also, if you add a decimal to the picture clause it works (because it's internally upsized to a floating point form, presumably a double (64-bit) form), etc.

Interesting quirk.

Best regards,
Rick C. Hodgin
317-879-6374
 
Numeric memory variables in VFP9 are never integers. Even if you set m.acct = CAST(0 as i) bith Vartype and List Memory show it as N (numeric). If it works because of initing in a different way, I'm baffled.

The help topic "Visual FoxPro Data and Field Types" also tells explicitly there only is the numeric data type, while integer is just available as a field type.


Bye, Olaf.
 
You can test it thusly:

test.prg:
foo1 = 0
foo2 = 0 + (9999999999 - 9999999999)
save to foo.hex

Load foo.hex in a hex editor capable of showing 64-bit floating points, and you'll see that foo1 has N(10) allocated for it stored as a 64-bit floating point, and foo2 has N(13,2) allocated for it also stored as a 64-bit floating point.

VFP9 apparently uses 32-bit integer values internally to store numeric values up to a certain size ((2^31)-1), and if the value contained in the variable is larger than that, or if it has decimals, then it falls back to a 64-bit double representation, and coordinates computations based on the field's decimals.

What you see as NUMERIC data types is an external representation visible to the application. I'm talking about what VFP9 is doing internally to actually process and store data.

Best regards,
Rick C. Hodgin
 
The more telling test:

test.prg:
foo1 = 0
foo2 = 0 + (9999999999 - 9999999999)
foo3 = 2147483647 && (2^31) - 1
foo4 = 2147483648 && 2^31
save to foo.hex
display memory like foo*

Note that foo1 and foo3 are shown without a decimal point in the non-rightmost column. And if you look at foo2 and foo4, they both have a decimal point (because of the automatic internal upsizing done by VFP9 to store variables in memory).

Best regards,
Rick C. Hodgin
 
All 4 variables are shown as type "N" and all of them are shown having decimal places at the right to me.
What are your settings, maybe something like SET COMPATIBLE will make the difference.

Bye, Olaf.
 
Rick,

Would you be able to upload that piece of code - a form and the SPR and the picture clause, so that we can reproduce? Dont forget also to include your settings like set("decimals")

Thanks,

JOckey(2)
 
Jockey2,

Sure. No special environment is set. It seems to work all the time.

Go in to FPW 2.6 and create a simple screen called "myfoo.scx". Create a single input box on the screen with the variable m.foo. In the setup / init code, use "m.foo = 0". Add a button with terminate read, and generate the SPR. It will be like the portion below.

Run it in FPW 2.6 with "do myfoo.spr" and it runs fine. Run the same in VFP9 and use these inputs:
(2^31) - 1 = 2,147,483,647 && Will work just fine
(2^31) = 2,147,483,648 && Will momentarily display a "numeric overflow" message.

The wait window message will only appear on the first input. So you'll have to exit the screen/form and restart. Once the value larger than (2^31)-1 is input, subsequent small or larger values operate correctly.

Next, you can verify that if you comment / un-comment and change the setup / init code from "m.foo = 0" to "m.foo = 0 + (9999999999 - 9999999999)" you'll see that it works fine.

Also, if you do this...

create table c:\temp\myfoo.dbf ( foo n(5,0) )
append blank
scatter memvar

...you'll note that m.foo (populated from the table, even though the table is an n(5,0) field) will also work like this without giving the message.

The "numeric overflow" message doesn't seem to affect anything. It just appears for a brief instant, and then continues. It is related to the 2^31 bit boundary, suggesting that VFP is using a 32-bit quantity for small values (more common) and when the numbers begin getting large, it switches to an alternate form of storage which, by examining the contents of the save to whatever.hex file, it appears to always be a 64-bit double floating point form, with a specified length and decimals.

Best regards,
Rick C. Hodgin

-----[ myfoo.spr ]-----
* *********************************************************
* * 05/21/2012 MYFOO.SPR 08:25:30
* *********************************************************
* * Description:
* * This program was automatically generated by GENSCRN.
* *********************************************************


#REGION 0
REGIONAL m.currarea, m.talkstat, m.compstat

IF SET("TALK") = "ON"
SET TALK OFF
m.talkstat = "ON"
ELSE
m.talkstat = "OFF"
ENDIF
m.compstat = SET("COMPATIBLE")
SET COMPATIBLE FOXPLUS

m.rborder = SET("READBORDER")
SET READBORDER ON

m.currarea = SELECT()


* *********************************************************
* * Windows Window definitions
* *********************************************************
IF NOT WEXIST("_3ia0i22x1")
DEFINE WINDOW _3ia0i22x1 ;
AT 0.000, 0.000 ;
SIZE 22.000,98.400 ;
FONT "MS Sans Serif", 8 ;
FLOAT ;
NOCLOSE ;
MINIMIZE ;
SYSTEM
ENDIF


* *********************************************************
* * MYFOO/Windows Setup Code - SECTION 2
* *********************************************************

#REGION 1
m.status = 0

**********
* Method 1, produces the message
*****
m.foo = 0

**********
* Method 2, does not produce the message
*****
*m.foo = 0 + (9999999999 - 9999999999)

**********
* Method 3, does not produce the message
*****
*set safety off
*create table c:\temp\myfoo.dbf ( foo n(5,0) )
*append blank
*scatter memvar


* *********************************************************
* * MYFOO/Windows Screen Layout
* *********************************************************

#REGION 1
IF WVISIBLE("_3ia0i22x1")
ACTIVATE WINDOW _3ia0i22x1 SAME
ELSE
ACTIVATE WINDOW _3ia0i22x1 NOSHOW
ENDIF
@ 3.769,19.600 GET m.foo ;
SIZE 1.000,44.800 ;
DEFAULT " " ;
FONT "MS Sans Serif", 8 ;
PICTURE "@K"
@ 5.538,33.600 GET m.status ;
PICTURE "@*HT Done" ;
SIZE 1.769,7.167,0.667 ;
DEFAULT 1 ;
FONT "MS Sans Serif", 8 ;
STYLE "B"
@ 1.000,9.600 SAY 'Use 2,147,483,647 or smaller to NOT produce the message.' + CHR(13) + ;
'Use 2,147,483,648 or larger to produce the "numeric overflow" message.' ;
SIZE 2.000,67.800, 0.000 ;
FONT "MS Sans Serif", 8 ;
STYLE "T"

IF NOT WVISIBLE("_3ia0i22x1")
ACTIVATE WINDOW _3ia0i22x1
ENDIF

READ CYCLE

RELEASE WINDOW _3ia0i22x1
SELECT (m.currarea)


#REGION 0

SET READBORDER &rborder

IF m.talkstat = "ON"
SET TALK ON
ENDIF
IF m.compstat = "ON"
SET COMPATIBLE ON
ENDIF
 
If you talk about fpw2.6, I believe anything. But you were talking about executing this converted to and within VFP9.

And there is no such thing as an integer variable type, that would explain what you see. I agree this is the value range of an integer up to 2,147,483,647. But that doesn't mean that variable type exists. Even with SET COMPATIBLE FOXPLUS I get this display:

Code:
FOO1                                                     Priv                              N             0                                                        (              0.00000000)      000051c9000c
FOO2                                                     Priv                              N             0.00                                                     (              0.00000000)      000051c9000c
FOO3                                                     Priv                              N             2147483647                                               (       2147483647.00000000)      000051c9000c
FOO4                                                     Priv                              N             2147483648                                               (       2147483648.00000000)      000051c9000c

Have you tried to build with the option recompile all? Maybe you inherit some old object code, that still behaves different than VFP9 does.

Bye, Olaf.
 
Olaf,

You're completely missing it. There are fundamental data types to the CPU itself, the kind that VFP9 must wield internally to process data. These are resolved then by VFP to be presented to the user application (the FoxPro data environment) as whatever types VFP converts them to, such as Numeric, etc.

I'm saying that internally, VFP is using the fast 32-bit forms to handle small integer numbers (small numbers without a decimal, such as 100 or 1,000,000). However, once the number overflows to some value larger than (2^31)-1, then it upsizes the internal storage mechanism to the slower form which is the 64-bit double.

In addition to examining the contents of the save to file, this could probably be tested by writing a SQL statement that computed only small numbers for a result, verses computing large values for a result, but on some large data set where the processing difference in speed between an integer or double would be observable. But, it doesn't matter.

-----
To answer your questions: Yes. As I said, for the example code I posted above I simply created a new screen and ran it directly from the command window and it produced the same message. It works correctly in 2.6.

Best regards,
Rick C. Hodgin
 
Rick said:
I'm saying that internally, VFP is using the fast 32-bit forms to handle small integer numbers (small numbers without a decimal, such as 100 or 1,000,000). However, once the number overflows to some value larger than (2^31)-1, then it upsizes the internal storage mechanism to the slower form which is the 64-bit double.

You're assuming that, and I know that foxpro does only work with 32bit integers in dbfs. Really, for sure. If you ever have worked very low level in FLL development and used the NameTableIndex, vfp's internal memory variable storage, yu'd see that VFP has no integer variable type on that level. It's really unintersting what the CPU could do, VFP is knid of an interpreter, and will always just use the floating point unit in regard of APU calculations.

In the end I just hint you this is not what to look for, even though it's clearly seen the effect is at the edge of the integer value range.

And in the end you know the solution can be to bind to a table instead of variables. So instead of scattering to variables, copy to a cursor you generate, having the fields, and then you've solved that problem, no matter what is going on behind the scenes.

Bye, Olaf.
 
Thank you for your help.

Best regards,
Rick C. Hodgin
 
Hi,

your quote
FWIW, there are closer to 1000 screens on this project than not.
unquote


Maybe it is time to switch and use classes......? This could prevent you from changing 1000+ screens, just change your class and you are done.

Regards,

Jockey(2)
 
History has been changed. I did not write "Thank you for your help."

My last posts have been deleted, and my ability to post under my original account suspended.

Don't cross Olaf.

Best regards,
Rick C. Hodgin
 
Jockey2,

It's a legacy application. We are moving it from FPW 2.6 to VFP9 to get it working. So far, only minor issues. It will be re-written at some point to use classes, but for now it will just be re-compiled.

Best regards,
Rick C. Hodgin
 
Olaf,

If you want to change history, please delete the entire thread. Don't put words in my mouth. I cannot imagine a time when I would thank you for this assistance you have doled out.

Best regards,
Rick C. Hodgin
 
When I try to post to tek tips under my original account, I am forcibly re-directed to yahoo dot com. Not kidding. This because I told Olaf his suggestion above of converting to string, then back to numeric, was insane (because it is).

Best regards,
Rick C. Hodgin
 
I did not write "Thank you for your help."

That's common when a user's identity has been 'bounced' out of the forum and/or when the forum moderators put a STOP to a non-useful and/or rude dialogue by an individual.

This is generally initiated by one or more "Red Flag' reports on someone's discussion behavior.

Good Luck,
JRB-Bldr






 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top