John Vey
Guest
|
Post by John Vey on Oct 15, 2018 19:28:32 GMT 1
Legacy code is behaving differently in vDos. The dBase function RECNO() is used to grab the current record number from a database. This is used to store the current pointer so the location can be recalled later in the code. When stored to a public memory variable, dBase assigns it to type N (Number) meaning it's a real number (Integer is NOT a type in dBase). When storing a record number 33001(or higher) into a memory variable and then displaying memory, it shows the real number value of 33000.99999999999820. And when the GOTO function is used, the record pointer goes to 33000 instead of the correct 33001. This does NOT behave like this in DOS BOX 0.74
I created a work around for this one instance(below), but know I've used this elsewhere and would have to search quite a bit of code to make sure everything behaves properly. I used the ROUND function to round to the nearest integer.
mTEST=ROUND(RECNO(),0)
Do you have any suggestions or ideas I might try?
|
|
|
Post by Jos on Oct 15, 2018 20:47:28 GMT 1
If you use version 2018.05.01, check if vDos.exe is dated May 30. If not, download vDos again.
Jos
|
|
Herman
Guest
|
Post by Herman on Oct 15, 2018 21:34:40 GMT 1
I've test it with Version 20180501.
? RECN() gives 33000 mTEST=ROUND(RECNO(),0) ? mTest gives 33000
and so on to the next records
Herman
|
|
John Vey
Guest
|
Post by John Vey on Oct 16, 2018 15:55:06 GMT 1
I'm using the May download...Properties of the certificate Herman...Can you try this simple test? I've tried it on 2 different databases with same result, so I don't think it has anything to do with data. And if you "Display Memory", you can see what it's storing in the memory variable.
|
|
John Vey
Guest
|
Post by John Vey on Oct 16, 2018 15:56:36 GMT 1
|
|
|
Post by Jos on Oct 16, 2018 17:04:05 GMT 1
Herman will have looked at dBaseV, no problems with that: This next version will have more widen normalization (rounding/truncating): Though still: I’ll have a quick look. But probably not to do much about that, there are some translation steps from the real FPU to the MS runtime routines to vDos’ FPU. I can’t just dismiss of too trailing many digits. So you should use ROUND() for now. Jos
|
|
Herman
Guest
|
Post by Herman on Oct 16, 2018 19:37:44 GMT 1
Hello John / Jos,
I tested it with dBase 5 as Jos also said, in vDos Version 2018.05.01
John, I have tested your example and always give 33001 as a record, both in the variable and with the function.
Herman
|
|
Herman
Guest
|
Post by Herman on Oct 16, 2018 20:04:28 GMT 1
Also the number that is between the brackets with DISPLAY MEMORY 33001.00000000000000
What can be of influence: SET PRECISION = 20 (institution with me)
If there are indexes attached to it, these can also influence the result in relation to the country code that does not match that which was originally created.
Furthermore, I can not imagine this as a bug in dBase, I would certainly have known.
Regards Herman
|
|
John Vey
Guest
|
Post by John Vey on Oct 19, 2018 14:08:12 GMT 1
Definitely not a bug in dBase. This code has been running for over 20+ years. It has always behaved as expected until now. As I mentioned, it works correctly in DOS BOX 0.74. I switched to vDos because of the file/record locking issues which was a much bigger problem. I've tested "SET DECIMAL TO" settings with no change in behavior.
I then tested Herman's suggestion in regards to "PRECISION". I have always used the default of 16. Setting precision to 20 produced the correct result. This is a much easier workaround. Thank you very much for that suggestion.
|
|
John Vey
Guest
|
Post by John Vey on Oct 19, 2018 17:40:39 GMT 1
I found another COMMAND that doesn't work with PRECISION AT 16 (Default). The COPY TO <file> STRUCTURE EXTENDED command will create a database with the structure of the currently opened database. Any Numeric Field with a width of 10 is incorrectly created with a width of 100. SET PRECISION TO 20 corrects that issue as well.
|
|
Herman
Guest
|
Post by Herman on Oct 19, 2018 17:46:28 GMT 1
I've tested with PRECISION = 16 in my config.db and the results are the same, so no problem here
I take a look in my history dBase info files from earlier versions for that sort of problems. There are issues that are not in dBase version 5. Maybe I can find something what is related to that problem.
Be patient I come back to this.
Regards Herman
|
|
Herman
Guest
|
Post by Herman on Oct 20, 2018 18:57:34 GMT 1
I have already checked my documentation and come to the following:
To better examine it, more information is needed.
What can all influence: What was the earlier basic Micosoft control system and dBase version when it used to go well? Important settings: SET DECIMALS TO SET NEAR TO.
As I have said before with me, I can not detect anything wrong and have tried it from different perspectives and changed settings (also restarted and that sort of thing).
I work with vDos Version 2018.05.01 and dBase version 5 x58 Aug 94. Previous versions have all a little problem what not is in de 5 version. I have enough applications running and also jump very often to records with SEEK, LOCATE, CONT, SKIP in DO WHIL loops with numbers in variables.
Playing in front of the recordpointer or after the recordpointer certainly played in previous dBase versions. But I do not see exactly why, except that they talk about settings.
I would not take DOSbox 0.74 as the right thing in this and just look at the basics in Microsoft control were things went right. That is where it all started with working well, I would think. For example, I have amply evaluated NTVDM MS-DOS and vDos in the correct operation with all my applications. This outcome was entirely positive; external calls there because that in MS-DOS with respect to CMD.EXE works differently. With DOSbox I have problems with big sizes of databases and it has a connstant negative crash effect.
Regards Herman
Sorry for my bad Englisch
|
|
|
Post by Jos on Oct 31, 2018 21:49:16 GMT 1
Found at last the bug: Converting a floating point value to an integer, vDos uses the nearbyint() MS runtime library function. First the rounding method has to be set, that wasn’t reset to the initial value before the function call. Didn’t seem important/needed, but not doing so had some minute side effects in rare situations. Probably just caused by 64-bit floating point numbers limitations in C, opposed to 80-bit with a real FPU.
Jos
|
|
|
Post by scotx on Aug 17, 2023 18:42:25 GMT 1
Hi Jos, you stated back in 2018 that the bug was located. Did you fix it? I've just recently gone back to testing a DBASE IV application using vDOS 2023-05-01. This bug with recno() still exists for us although we did build in the round fix as stated in this chat when we were testing vDOS 2022-05-01 last year.
In the meantime I've built a small dbase PRG that highlights the problem as I can't send you code from our customer. Simply loops through a table of 33000 records. The recon() problem occurs when record pointer hits 32768 (does this dividable by 8 number ring a bell ;-) )
The CONFIG.txt has FPUAWARE = 2
Here is my test code to provoke the issue:
************************************************************************ ** Example code to provoke recno() problem with dbase on vDOS 2023-05-01 ** Date: 17-AUG-2023 ** Requirements: The test DBF table, in this case E:\zMUKL\DATEN\prokoll ** must have at least 33000 records ************************************************************************ procedure vDOSTest pSwitch = "WITHBUG" && WITHBUG or NOBUG
use ("E:\zMUKL\DATEN\prokoll") in 1 select 1 && PROKOLL.DBF
set talk off
? "Running..." scan while .not.eof() saverec = recno() && normal coding fixedrec = round(recno(),0) && Fix added for running under vDOS
if fixedrec > 32760 ? "> normal stored recno: "+ltrim(str(saverec))+" - " ?? " fixed stored recno:"+ltrim(str(fixedrec))+" - " ?? " actual recno: "+ltrim(str(recno())) do case case UPPER(pSwitch) = 'NOBUG' go fixedrec case UPPER(pSwitch) = 'WITHBUG' go saverec otherwise wait 'Parameter NOBUG or WITHBUG missing' quit endcase endif
&& Catch location where the problem starts if (fixedrec = 32768).or.(fixedrec > 32768) wait 'Continue? (Y/N)' TO M_ans if UPPer(M_ans) = 'N' quit endif endif endscan return Previous tests of the code with the DBDosV2 and the latest DOSBox-X as of 17-AUG-2023 have worked without the round() function.
Regards
Scot-X
|
|
|
Post by Jos on Aug 17, 2023 21:21:21 GMT 1
That surprised me, I thought (dBase IV) FPU problems would be fixed. Running your test I got: Disabling hardware FPU support (FPUAWARE=0) gave the correct: I’ll have a look, though that could take some time. For now just disable the vDos FPU. Jos
|
|