Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion GroupsVB SyntaxEnterprise DevelopmentDatabase AccessControlsCOMWin APICrystal ReportDeploymentGeneralGeneral 2
Related Topics
VB.NET / ASP.NETMS SQL ServerMS AccessOther Database ProductsMore Topics ...

VB Forum / Controls / September 2008



Tip: Looking for answers? Try searching our database.

Double data Type limits

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Bob - 31 Aug 2008 01:21 GMT
Hi Everyone:

I was just goofing around, and I was wondering if anyone knows of any
example that can get around the limits of a Double data type in VB 6.  For
example if you look at the calculator in windows, you can easily go beyond
the limits of double, e.g. 1000! (factorial of 1000).

I appreciate any resources or web sites you can give me.

Thanks;

Bob
MikeD - 31 Aug 2008 02:17 GMT
> Hi Everyone:
>
[quoted text clipped - 4 lines]
>
> I appreciate any resources or web sites you can give me.

How about VB's own Help for a resource? It lists the ranges of all data
types.

Signature

Mike
Microsoft MVP Visual Basic

Bob - 31 Aug 2008 03:25 GMT
I know the ranges.  But, I need to go beyond 1.7E308.  I could not see
anything on this on help.  As you can see 1000! = 4.02E+2567, which is
outside the range of a double.

Bob

>> Hi Everyone:
>>
[quoted text clipped - 7 lines]
> How about VB's own Help for a resource? It lists the ranges of all data
> types.
Schmidt - 01 Sep 2008 06:16 GMT
> I know the ranges.  But, I need to go beyond 1.7E308.
> I could not see anything on this on help.  As you can see
> 1000! = 4.02E+2567, which is outside the range of a double.

As Paul said, no other way than to either use a lib with "long-math"
support (there should be many of these libs out there - and IIRC
e.g. Java has this builtin) - or to write your own, based on Strings
or ByteArrays...

It's somewhat like you've learned to multiply or divide in
school  ... to get an idea, what optimizations can be done
"on top" of such a scool-like algo (you don't need to process
each digit on a 10th-base)...
Here's a (somewhat rusty) LongMul-routine, wich I wrote ca.
10 years ago. It is able to multiply two 600-digit-numbers in
under 4 msec on an old PIII 500.

'****Into a Form
Option Explicit
Private Declare Function QueryPerformanceFrequency& Lib "kernel32" (X@)
Private Declare Function QueryPerformanceCounter& Lib "kernel32" (X@)

Private Sub Form_Click()
Dim R$, Factor$: Const L& = 600
 Factor = String(L, "9")
 R = LongMul(Factor, Factor)
 'small test for "pure" 9'er
 If R = String(L - 1, "9") & 8 & String(L - 1, "0") & 1 Then
   Print "correct result for 'square-niners'"
 End If
End Sub

Private Function LongMul$(S1$, S2$)
Dim i&, j&, d&, m&, JArr$(), L1&(), L2&(), Sum@(), S, t#
 t = HPTimer
 If S1 = "" Then S1 = "0"
 If S2 = "" Then S2 = "0"
 If Left(S1, 1) = "-" Then S1 = Mid(S1, 2): S = True
 If Left(S2, 1) = "-" Then S2 = Mid(S2, 2): S = Not S

'Convert to Long-Array
 m = Len(S1) + 1: d = 4: i = 0
 Do: m = m - 4: If m <= 0 Then d = 4 + m - 1: m = 1
   ReDim Preserve L1(i): L1(i) = Mid(S1, m, d): i = i + 1
 Loop Until m = 1
 m = Len(S2) + 1: d = 4: i = 0
 Do: m = m - 4: If m <= 0 Then d = 4 + m - 1: m = 1
   ReDim Preserve L2(i): L2(i) = Mid(S2, m, d): i = i + 1
 Loop Until m = 1
Print "Transform to LongArr: " & CLng((HPTimer - t) * 1000)

'Multiply and Group-accumulation
t = HPTimer
 ReDim Sum(UBound(L1) + UBound(L2))
 For i = 0 To UBound(L1)
   For j = 0 To UBound(L2)
     Sum(i + j) = Sum(i + j) + L1(i) * L2(j)
   Next j
 Next i
Print "Multiply: " & CLng((HPTimer - t) * 1000)

'Reconvert to String-Parts
t = HPTimer
 ReDim JArr(UBound(Sum))
 For i = 0 To UBound(Sum) - 1
   JArr(UBound(Sum) - i) = Right("000" & Sum(i), 4)
   Sum(i + 1) = Sum(i + 1) + Int(Sum(i) / 10000)
 Next i
 JArr(UBound(Sum) - i) = IIf(S, "-", "") & Sum(i)
Print "Prepare for Output: " & CLng((HPTimer - t) * 1000)

'Join&Exit
t = HPTimer
 LongMul = Join(JArr, "")
Print "Join&Exit: " & CLng((HPTimer - t) * 1000)
End Function

Private Function HPTimer#()
Dim X@: Static Frq@
 If Frq = 0 Then QueryPerformanceFrequency Frq
 If QueryPerformanceCounter(X) Then HPTimer = X / Frq
End Function

Olaf
Bob - 01 Sep 2008 20:48 GMT
Thank you Olaf.  In the next few days, I will take a look at your code, and
expand on it.  Thanks for all your help.

Bob

>> I know the ranges.  But, I need to go beyond 1.7E308.
>> I could not see anything on this on help.  As you can see
[quoted text clipped - 80 lines]
>
> Olaf
Tony Proctor - 04 Sep 2008 10:11 GMT
Use logs Bob, e.g the following calculates your 1000!

Dim i As Integer, fRes As Double

i = 1000
Do While i > 1
   fRes = fRes + Log(i) / Log(10)
   i = i - 1
Loop
Debug.Print "Answer = " & 10 ^ (fRes - Int(fRes)) & "E" & Int(fRes)

   Tony Proctor

>I know the ranges.  But, I need to go beyond 1.7E308.  I could not see
>anything on this on help.  As you can see 1000! = 4.02E+2567, which is
[quoted text clipped - 13 lines]
>> How about VB's own Help for a resource? It lists the ranges of all data
>> types.
Bob - 06 Sep 2008 18:55 GMT
Thanks Tony.

Bob
> Use logs Bob, e.g the following calculates your 1000!
>
[quoted text clipped - 26 lines]
>>> How about VB's own Help for a resource? It lists the ranges of all data
>>> types.
Ralph - 31 Aug 2008 04:09 GMT
> Hi Everyone:
>
[quoted text clipped - 4 lines]
>
> I appreciate any resources or web sites you can give me.

A Double is a floating point number stored as eight bytes (64 bits). The
range of numbers you can hold in a Double is vast: from positive 1.79E308 to
negative 1.79E308. A Double is limited to 15 significant figures.

That limitation also actually skews the scale of the data. As the Integer
portion grows the scale of the fractional portion decreases.

But you asked what if we want to represent even larger numbers?

The clue to how to do that is contained in VB's Currency Datatype. It
permits up to 15 digits to the left of the decimal point, resulting in a
range of approximately -922,337,000,000,000 to +922,337,000,000,000.
Currency is actually an integer type internally. It is scaled by a factor of
10,000 to give four digits to the right of the decimal point. You can apply
this design by writing your own wrapper for multiple longs. Each
representing a factored range.

There is probably some code out there for doing this. Of course some numbers
are not worth it. We can easily write an expression that represents a number
greater than grains of sand in the Universe. <g>

-ralph
Bob - 01 Sep 2008 00:44 GMT
Thank you Ralph.

>> Hi Everyone:
>>
[quoted text clipped - 34 lines]
>
> -ralph
PeterD - 31 Aug 2008 20:51 GMT
>Hi Everyone:
>
[quoted text clipped - 8 lines]
>
>Bob

Bob, you'd probably get better replies if you would post these in the
*correct* group, say Microsoft.Public.VB.General.Discussion. I don't
see this has anything to do with VB controls, which is what the group
you posted in is for.
expvb - 08 Sep 2008 16:07 GMT
This VB6 calculator can handle unlimited digits. Source code is included:

http://www.karenware.com/powertools/ptcalc.asp
Bob - 08 Sep 2008 19:48 GMT
Thank you.  That is what I was looking for.  Have a great week.

Bob

> This VB6 calculator can handle unlimited digits. Source code is included:
>
> http://www.karenware.com/powertools/ptcalc.asp
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.