Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Πρόβλημα με τύπο Μεταβλητής

Îåêßíçóå áðü ôï ìÝëïò AlKiS. Τελευταία δημοσίευση από το μέλος AlKiS στις 26-12-2011, 16:46. Υπάρχουν 6 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  26-12-2011, 02:53 68708

    Πρόβλημα με τύπο Μεταβλητής

    Γεια σας (.)DotNetZone !!

    Έφτιαξα ένα function για να μου υπολογίζει υπεργεωμετρικές κατανομές, αλλά έχω ένα πρόβλημα. Όταν του βάζω να υπολογίσει το 80 ανά 20 δεν μπορεί να το κάνει γιατί στο πρώτο βήμα που πάει να υπολογίσει το (80)20  ( 80*79*78*77*76*75*74*73*72*71*70*69*68*67*66*65*64*63*62*61*60 ) κολλάει στο νούμερο 5974790569203456000 το οποίο είναι ουσιαστικά το  80*79*78*77*76*75*74*73*72*71. Δηλαδή δεν έφτασε ούτε στη μέση... 

    Το έβαλα ulong μιας που ξέρω ότι θα υπολογίζω μόνο θετικούς αριθμούς, και το έβαλα και long για να δέχεται τεράστιες τιμές (64bit).

    Παρόλαυτα όμως ξέρω ότι μπορεί να γίνει, γιατί στην R ( http://www.r-project.org/ ) πάτησα να μου κάνει τον πολλαπλασιασμό και μου το έβγαλε ολόκληρο χωρίς πρόβλημα..

    Είναι κρίμα, γιατί σαν function δουλεύει μια χαρά, αλλά υπάρχει αυτό το πρόβλημα όταν μπει μεγάλος αριθμός

    Σαν τι να το ορίσω? δεν βρήκα μεγαλύτερο...


    Κάτω παραθέτω τα function, όποιος θέλει να το χρησιμοποιήσει είναι ελεύθερος:

        Public Function Hypergeometric_Distribution(ByVal ν As LongByVal k As LongByVal N As LongByVal r As LongAs Decimal
            Dim Result As Decimal = BinomialCoefficient(ν, k) * BinomialCoefficient(N - ν, r - k) / BinomialCoefficient(N, r)
            Return Result
        End Function
     
        Public Function BinomialCoefficient(ByVal Kati As LongByVal AnaKati As LongAs Decimal
            Dim Result As Decimal = 0
     
            If Kati <> AnaKati And Kati <> 0 And AnaKati <> 0 And Kati > AnaKati Then
                Dim LoopCount As Integer = 0
     
                Dim FacUp As Long = Kati
                Dim FacDown1st As Long = AnaKati
                Dim FacDown2nd As Long = Kati - AnaKati
     
                Dim DividerDown As ULong = 1
                Dim DividendUp As ULong = 1
     
                If Kati / AnaKati <= 2 Then                                     'if First is <=2times the Second then the 1st Factorial is eliminated
                    For i As Long = FacUp To FacDown1st + 1 Step -1
                        DividendUp = DividendUp * CULng(FacUp - (LoopCount))    'Calculating the Factorial Up
                        LoopCount += 1
                    Next
                    FacDown1st = 1                                              '1st Factorial gets eliminated
     
                    If FacDown2nd <> 0 AndAlso FacDown2nd <> 1 Then
                        Dim BeginningOfLoop As Long = FacDown2nd - 1
                        For i As Long = BeginningOfLoop To 1 Step -1
                            FacDown2nd = FacDown2nd * i                         'Calculating the Factorial Down
                        Next
     
                    Else
                        FacDown2nd = 1                                          'Factorial 1 and 0 = 1
                    End If
                Else                                                            'if First is >=2times the Second then the 2nd Factorial is eliminated
                    For i As Long = FacUp To FacDown2nd + 1 Step -1
                        DividendUp = DividendUp * CULng(FacUp - (LoopCount))    'Calculating the Factorial Up
                        LoopCount += 1
                    Next
                    FacDown2nd = 1                                              '2nd Factorial gets eliminated
     
                    If FacDown1st <> 0 AndAlso FacDown1st <> 1 Then
                        Dim BeginningOfLoop As Long = FacDown1st - 1
                        For i As Long = BeginningOfLoop To 1 Step -1
                            FacDown1st = FacDown1st * i                         'Calculating the Factorial Down
                        Next
     
                    Else
                        FacDown1st = 1                                          'Factorial 1 and 0 = 1
                    End If
                End If
     
                DividerDown = CULng(FacDown1st * FacDown2nd)
                Result = CDec(DividendUp / DividerDown)
     
            Else
                Result = 0
            End If
     
            Return Result
        End Function


  •  26-12-2011, 11:07 68711 σε απάντηση της 68708

    Απ: Πρόβλημα με τύπο Μεταβλητής

    Καλημέρα!

    Στο .NET 4 υπάρχει ο τύπος System.Numerics.BigInteger. Ίσως αυτός να σε βολέψει.

    Επίσης, διάβασε και αυτό το άρθρο από το stackoverflow.com.

    Τάσος Καραγιάννης

    Baby debugging steps...
  •  26-12-2011, 11:49 68712 σε απάντηση της 68711

    Απ: Πρόβλημα με τύπο Μεταβλητής

    Ευχαριστώ πολύ!

    Δουλεύει. Δεν υπάρχει πια το overflow πρόβλημα. Παρόλαυτα όμως, βγήκε ένα καινούργιο πρόβλημα.

    Επειδή το αποτέλεσμα της διαίρεσης είναι 0,0000001672724 (το ξέρω γιατί έκανα την διαίρεση στην "R")

    δηλαδή επειδή το αποτέλεσμα είναι πολύ μικρό, μου βγάζει ότι είναι ένα σκέτο μηδενικό (0).

    Αυτό δεν μου κάνει εμένα όμως. Μια πιθανότητα τυχαίων συμβάντων δεν μπορεί να πάρει ποτέ την τιμή 1 (100%) ή την τιμή 0 (0%). Πρέπει να κυμαίνεται ανάμεσα.


    Το αποτέλεσμα το έχω να μου το βγάζει σαν Decimal το οποίο είναι διπλάσια καλό απο το double (έχει διπλάσια ακρίβεια), και πάλι όμως, μου το βγάζει σκέτο 0.

    Τι να κάνω για να μου λέει "0.0000001672724" όπως κάνει η R?????


    (P.S. δείτε και την άλλη ερώτησή μου εδώ: http://www.dotnetzone.gr/cs/forums/thread/68702.aspx )


  •  26-12-2011, 16:03 68714 σε απάντηση της 68712

    Απ: Πρόβλημα με τύπο Μεταβλητής

    Ο BigInteger δεν είναι τίποτε άλλο παρά ένας... integer! Δυστυχώς, δεν υπάρχει κάποιο data type στο .NET που να καλύπτει arbitrary σενάρια ως προς την ακρίβεια των υπολογισμών. Άλλες φορές θέλουμε το αποτέλεσμα σε ακεραίους και άλλες φορές σε δεκαδικούς. Θα πρέπει να χρησιμοποιήσεις ένα library τρίτου κατασκευαστή, όπως το GMP. Υπάρχει wrapper για .NET.

    Ακόμα κι ένας άνθρωπος μπορεί ν' αλλάξει τον κόσμο. Μη θέλεις να κυβερνήσεις. Απλά δείξε το μονοπάτι κι ο κόσμος θ' ακολουθήσει!!
  •  26-12-2011, 16:31 68715 σε απάντηση της 68714

    Απ: Πρόβλημα με τύπο Μεταβλητής

    ευχαριστώ,

    αλλά βρήκα την απάντηση μόνος μου τελικά.. το μόνο που έπρεπε να αλλάξω τον τύπου του function BinomialCoefficient απο BigInteger σε Decimal. 


  •  26-12-2011, 16:40 68716 σε απάντηση της 68715

    Απ: Πρόβλημα με τύπο Μεταβλητής

    Η λύση που έδωσες είναι προσωρινή. Σε άλλο πρόβλημα, που οι απαιτήσεις σε ακρίβεια θα είναι μεγαλύτερες, πάλι θα χτυπήσεις "τοίχο".

    Ακόμα κι ένας άνθρωπος μπορεί ν' αλλάξει τον κόσμο. Μη θέλεις να κυβερνήσεις. Απλά δείξε το μονοπάτι κι ο κόσμος θ' ακολουθήσει!!
  •  26-12-2011, 16:46 68717 σε απάντηση της 68716

    Απ: Πρόβλημα με τύπο Μεταβλητής

    εν μέρη έχεις δίκιο,

    παρόλαυτα όμως, η ακρίβεια που έχω με το decimal είναι διπλάσια της ακρίβειας που δίνει η ίδια η R (που είναι και μαθηματική καθαρά γλώσσα), οπότε πιστεύω ότι μου φτάνει (προς το παρόν - γιατί πνίγομαι απο δουλειές και δεν έχω χρόνο για ψάξιμο).

    Θα δοκιμάσω το πρόγραμμα που μου πρότεινες όταν βρω χρόνο.


    ευχαριστώ πολύ για το χρόνο σου φίλε μου.

    Και χρόνια πολλά (να μπούμε και λίγο στο χριστουγεννιάτικο πνεύμα) :)


Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems