محاسبات ریاضی بزرگ

loo30fer

کاربر متخصص مولتی مدیا بیلدر
با سلام
من تو ویژوال بیسیک میخوام دو عدد بزرگ رو جمع بزنم که حاصل اون یه عدد 99 رقمی میشه.
من این کد رو نوشتم:
Dim d1 As Double
Dim d2 As Double
Dim d3 As Currency
d1 = Text1
d2 = Text2
Text3 = d1 + d2
حالا مشکلم اینجاست که حاصل جمع رو به نماد علمی بر می گردونه.
حالا برای تبدیلش به عدد معمولی باید چگونه عمل کنم(حاصل جمع این شده 1E+97).
ممنون میشم از راهنمایتون.
 

the_king

مدیرکل انجمن
با سلام
من تو ویژوال بیسیک میخوام دو عدد بزرگ رو جمع بزنم که حاصل اون یه عدد 99 رقمی میشه.
من این کد رو نوشتم:
Dim d1 As Double
Dim d2 As Double
Dim d3 As Currency
d1 = Text1
d2 = Text2
Text3 = d1 + d2
حالا مشکلم اینجاست که حاصل جمع رو به نماد علمی بر می گردونه.
حالا برای تبدیلش به عدد معمولی باید چگونه عمل کنم(حاصل جمع این شده 1E+97).
ممنون میشم از راهنمایتون.
1E+97 یعنی یک 1 به همراه 97 تا صفر، یعنی عدد مورد نظر بصورت تقریبی ذخیره میشه.

Double یک نوع داده با ممیز شناور است، یعنی اعداد رو به شکل (x * (10 ^ y ذخیره می کنه.
اگر تعداد ارقام عدد مورد نظر زیاد نباشه، مقدار y رو 0 قرار میده و x همون عدد مورد نظر میشه، اما
ظرفیت x یک تعداد رقم مشخصه حدودا 14 رقم و برای اعداد با تعداد ارقام بیشتر جا نداره، هر جا که دید
تعداد ارقام x از ظرفیت اش بیشتر شد، از رقم های سمت راست x کم می کنه و بجاش مقدار y رو کم و زیاد
می کنه تا حاصل به عدد مورد نظر نزدیکتر بشه. اینطوری یکسری ارقام عدد مورد نظر با 0 جایگزین میشه،
یعنی عدد تقریبی ذخیره میشه و دقیق نیست. اما این مزیت رو داره که با کم زیاد کردن y میشه اعداد خیلی خیلی
کوچیک و خیلی خیلی بزرگ رو ذخیره کرد، مثلا یک عدد 308 رقمی.

Currency یک نوع داده بدون ممیز شناور است، یعنی در حقیقت یک نوع داده صحیح بدون اعشار 64 بیتی است که
همیشه نتیجه محاسباتش رو تقسیم بر 10000 می کنند تا چهار رقم بعد از اعشار هم داشته باشه. از اونجایی
هم که 64 بیتی است محدوده اعدادش از 922337203685477.5807 بیشتر نمیشه، حتی یک ده هزارم.
Currency رو ساخته اند تا محاسبات مالی باهاش انجام بشه، چون در محاسبات مالی حتی یک ریزه تقریب اعشاری
هم نباید باشه.

طبیعتا نه Currency و نه Double برای کاری که شما می خواهید انجام بدید مناسب نیستند، چون هیچکدوم اطلاعات
99 رقم رو نگه نمی دارند، Currency که هیچ، اصلا نمی تونه همچین عدد بزرگی رو ذخیره کنه. Double هم که
ذخیره اش می کنه بجای ارقام پایینی 0 ذخیره می کنه چون فقط برای ارقام بالایی جا داره.

شما باید محاسبه رو با کمک آرایه انجام بدید، هم با اعداد اعشاری جواب میده و هم صحیح، البته فقط
برای اعداد غیر منفی :
کد:
Private Type Num
    Major() As Byte
    Minor() As Byte
    MajorCount As Long
    MinorCount As Long
End Type

Private Sub Form_Load()
    Dim d1 As Num
    Dim d2 As Num
    Dim d3 As Num
    d1 = TextToNum(Text1.Text)
    d2 = TextToNum(Text2.Text)
    d3 = AddNum(d1, d2)
    Text3.Text = NumToText(d3)
End Sub

Private Function AddNum(ByRef Number1 As Num, ByRef Number2 As Num) As Num
    Dim Pos As Long
    Dim Number As Num
    Dim Carry As Long
    Dim Digit As Long
    With Number
        .MajorCount = Max(Number1.MajorCount, Number2.MajorCount) + 1
        .MinorCount = Max(Number1.MinorCount, Number2.MinorCount)
        ReDim .Major(0 To .MajorCount)
        ReDim .Minor(0 To .MinorCount)
        ReDim Preserve Number1.Minor(0 To .MinorCount)
        ReDim Preserve Number2.Minor(0 To .MinorCount)
        For Pos = .MinorCount - 1 To 0 Step -1
            Digit = Carry + Number1.Minor(Pos) + Number2.Minor(Pos)
            .Minor(Pos) = Digit Mod 10
            Carry = Digit \ 10
        Next
        ReDim Preserve Number1.Major(0 To .MajorCount)
        ReDim Preserve Number2.Major(0 To .MajorCount)
        For Pos = 0 To .MajorCount - 1
            Digit = Carry + Number1.Major(Pos) + Number2.Major(Pos)
            .Major(Pos) = Digit Mod 10
            Carry = Digit \ 10
        Next
        .Major(.MajorCount) = Carry
    End With
    AddNum = Number
End Function

Private Function Max(ByVal Number1 As Variant, ByVal Number2 As Variant) As Variant
    If Number1 > Number2 Then
        Max = Number1
    Else
        Max = Number2
    End If
End Function

Private Function NumToText(ByRef Number As Num) As String
    Dim Pos As Long
    Dim Started As Boolean
    Dim MajorText As String
    Dim MinorText As String
    With Number
        For Pos = .MajorCount - 1 To 0 Step -1
            Select Case .Major(Pos)
            Case 0
                If Started Or Pos = 0 Then MajorText = MajorText & "0"
            Case 1 To 9
                Started = True
                MajorText = MajorText & Chr(.Major(Pos) + 48)
            End Select
        Next
       Started = False
        For Pos = .MinorCount - 1 To 0 Step -1
            Select Case .Minor(Pos)
            Case 0
                If Started Then MinorText = "0" & MinorText
            Case 1 To 9
                Started = True
                MinorText = Chr(.Minor(Pos) + 48) & MinorText
            End Select
        Next
    End With
    If Len(MinorText) > 0 Then
        NumToText = MajorText & "." & MinorText
    Else
        NumToText = MajorText
    End If
End Function

Private Function TextToNum(ByVal Text As String) As Num
    Dim Pos As Long
    Dim Number As Num
    Dim MajorText As String
    Dim MinorText As String
    With Number
        Text = Trim(Text)
        Pos = InStr(Text, ".")
        If Pos = 0 Then Pos = Len(Text) + 1
        MajorText = Left(Text, Pos - 1)
        MinorText = Mid(Text, Pos + 1)
        .MajorCount = Len(MajorText)
        .MinorCount = Len(MinorText)
        ReDim .Major(0 To .MajorCount)
        ReDim .Minor(0 To .MinorCount)
        For Pos = 1 To Len(MajorText)
            .Major(.MajorCount - Pos) = Asc(Mid(MajorText, Pos, 1)) - 48
        Next
        For Pos = 1 To Len(MinorText)
            .Minor(Pos - 1) = Asc(Mid(MinorText, Pos, 1)) - 48
        Next
    End With
    TextToNum = Number
End Function
 
آخرین ویرایش:

جدیدترین ارسال ها

بالا