[Info-vax] Is this a Bug ?
David Froble
davef at tsoft-inc.com
Tue Apr 17 11:42:37 EDT 2012
StGallen wrote:
> Dear All
>
> VMS 7.3-1
> DEC Basic 1.4
>
> I have a situation where I need to check if the integer part of a decimal number is > 0. The number could be upto 999999999999.999999. Thus, I need to check if the integer part 999999999999 is greater than 0.
>
> INTEGER(sNum,LONG) works but throws 52 - Illegal Number since the LONG cannot handle a number this big. My alternative was to use QUAD.
> This gives me BAS-F-MEMMANVIO, Memory management violation
>
> Refering to the BASIC manual, I have added: option handle = severe
> Also I have compiled with the /CHECK qualifier.
>
> Any ideas are most gratefully welcome.
>
>
>
> 10
> option handle = severe
>
> %include "STR$ROUTINES" %from %library "sys$library:basic$starlet"
> %include "$lnmdef" %from %library "sys$library:basic$starlet"
> %include "$libclidef" %from %library "sys$library:basic$starlet"
>
>
> DECLARE STRING sNUM
> DECLARE STRING sPI
> DECLARE STRING sPF
> DECLARE LONG lSTAT
> sPI = ""
> sPF = ""
>
> LINPUT "Enter a number ";sNUM
> lStatus = STR$ELEMENT(sPI,0,".",sNUM) ! Integer part
> lStatus = STR$ELEMENT(sPF,1,".",sNUM) !fractional part
>
> IF INTEGER(sPI,QUAD) = 0 !<---- program aborts here
> THEN
> PRINT "INT part is 0"
> ELSE
> PRINT "INT part is ";INTEGER(sPI,QUAD)
> END IF
> 32767 END
10 Declare Double Z1, Z2
Z1 = 999999999999.999999
Z2 = Fix( Z1 )
Print Format$( Z1 , "#,###,###,###,###.######" )
Print Format$( Z2 , "#,###,###,###,###.######" )
If Z2 > 0.
Then Print "True"
Else Print "False"
End If
End
Ready
run
NONAME 17-APR-2012 11:24
1,000,000,000,000.000000
1,000,000,000,000.000000
True
Ready
Ok, what's wrong with the above? Double FP has if I remember correctly 15 digits of
precision, but can handle larger numbers. Since FP isn't precise (past the first 15
digits) Format$() is rounding the output.
If all you want to do is get the "whole" part of a number, "Fix()" is what you want.
Warning, if you use the above code to test, and put more than 6 digits to the right of the
DP, Format$() will round. But, you stated your needs for the fractional part was only 6
digits, so I coded the Format$() mask accordingly.
Warning #2, FP is NOT absolutely precise. I remember some years ago Randy Parks ranting
about some FP values that would give some rather interesting results. It's just the way
the FP works.
Hmmm......
Re-reading your code, you're input is a string, not a DECIMAL data type, (dumb Dave, you
assumed again), you can use Val() to convert it to a floating point number. As long as
you have less than 14-15 digits to the left of the DP, then Fix() will give you a valid
whole part of the number.
More information about the Info-vax
mailing list