Re: Scientific Notation by Joe
Joe
Wed May 25 09:15:18 CDT 2005
Hi Bob
"Bob Barrows [MVP]" <reb01501@NOyahoo.SPAMcom> wrote in message
news:u3FEQ0JYFHA.612@TK2MSFTNGP12.phx.gbl...
> karena wrote:
>> 72.5 needs to be written to a text file as 7.25E+01
>> and 0.0038472 has to be written as 3.8472E-03
>>
> OK, I was intrigued. Here is a quickie (it needs error-handling and input
> validation) that will handle positive numbers between 1.0E-308 and
> 1.0E+308:
>
> function NumToExpNot(byval val)
> dim i, newval, mult, sign
> val = cdbl(val)
> if val > 0 then
> if val >= 1 then
> mult=-1
> sign="+"
> else
> mult=1
> sign="-"
> end if
> i=0
> newval=val
> do until newval >= 1 AND newval < 10
> i = i + 1
> newval = val * 10^(mult * i)
> loop
> newval=newval & "E" & sign & right("000" & i,3)
> NumToExpNot=newval
> else
> end if
> end function
>
> This should give you the idea if you need to handle negative numbers ...
>
> HTH,
> Bob Barrows
> --
> Microsoft MVP -- ASP/ASP.NET
> Please reply to the newsgroup. The email account listed in my From
> header is my spam trap, so I don't check it very often. You will get a
> quicker response by posting to the newsgroup.
>
The problems are: (1) longer double-precision numerics automatically
convert to the E notation when you try to manipulate them as strings (a
curiousity of BASIC); and (2) double-precision rounding sets in even at low
powers. Here's a slightly updated version of an old QuickBASIC function
that works with any numeric value within double-precision range, or with any
length and without double-precision rounding, if submitted as a string, by
manipulating the numeric argument purely as a string. Check the differences
in examples 3 and 4.
-----
n1= 72.5
n2= .0038472
n3= 500000000000000000005.000000000005
n4= "500000000000000000005.000000000005"
wscript.echo sciEFmt(n1) _
& vbCr & sciEFmt(n2) _
& vbCR & sciEFmt(n3) _
& vbCR & sciEFmt(n4)
function SciEFmt (byVal vxNum)
' returns string, "n.nn...E+/-n"
' at least 1 decimal position
' at least 2 power positions
' vxNum= positive numeric value or string
' returns 0, "" or Empty as "0"
' returns Empty if not numeric or negative
on error resume next
dim vsNum: vsNum= ucase(cstr(vxNum))
if err then err.clear: exit function
on error goto 0
if (vsNum="") then sciEFmt= 0: exit function
if not isnumeric(vxNum) then exit function
if (vxNum<0) then exit function
dim viDelim, viE, vsSgn: do
viDelim= instr(vsNum, "E"): if viDelim then
vsSgn= mid(vsNum, viDelim +1, 1)
viE= mid(vsNum, viDelim +2)
vsNum= left(vsNum, viDelim -1)
exit do
end if
do while (right(vsNum, 1)="0")
vsNum= left(vsNum, len(vsNum) -1)
loop
if (vsNum="") then sciEFmt= "0": exit function
viDelim= instr(vsNum & ".", ".")
dim vsInt: vsInt= left(vsNum, viDelim -1)
do while (left(vsInt, 1)="0")
vsInt= mid(vsInt, 2)
loop
dim vsFrac: vsFrac= mid(vsNum, viDelim +1)
do while (right(vsFrac, 1)="0")
vsInt= left(vsFrac, len(vsFrac) -1)
loop
if (len(vsInt & vsFrac)=0) then sciEFmt= "0": _
exit function
select case vsInt
case "": viE= 1
do while (left(vsFrac, 1)="0")
vsFrac= mid(vsFrac, 2): viE= viE +1
loop: vsNum= vsFrac: vsSgn= "-"
case else: viE= len(vsInt) -1
vsNum= vsInt & vsFrac: vsSgn= "+"
end select
loop until true
sciEFmt= left(vsNum, 1) & "." _
& array("0", mid(vsNum, 2))(sgn(len(vsNum) -1)) _
& "E" & vsSgn & array("", "0")(abs(viE<10)) & viE
end function
-----
Joe Earnest