Avatar billede fanatic Nybegynder
15. april 2005 - 14:24 Der er 12 kommentarer og
1 løsning

Arbejde med kæmpe tal i programmering!

Hej Eksperter!

Jeg sidder og arbejder på en applikation (c# .NET) som bla. skal kunne udregne store tal. Et eksempel er 1000! eller 2^1000.
Resultatet af disse udtryk er for store til at de kan vises uden at bruge eksponential notation som eks. 48.145E+44. JEg vil gerne have hele tallet vist.

Er der nogen som kan give mig en opskrift på hvordan dette kunne gøres? Et link til en artikel kan også bruges.

Mvh.

Fanatic
Avatar billede dbangx Nybegynder
15. april 2005 - 14:48 #1
jeg har fundet et kodeeksempel, hvor en gut udregner 2k decimaler på pi... det kan være der er noget du kan bruge :-)
http://www.personalmicrocosms.com/html/cspc_samples_pi.html
Avatar billede nielle Nybegynder
15. april 2005 - 15:12 #2
Måske er det dette du leder efter?

http://www.codeproject.com/csharp/BigInteger.asp
Avatar billede nielle Nybegynder
16. april 2005 - 20:51 #3
Herunder er noget jeg lige har hakket sammen. Det er en god øvelse i operator-overload. Pt. understøtter klassen kun addition og multiplikation.
Avatar billede nielle Nybegynder
16. april 2005 - 20:51 #4
// (c) 2005 Copyright, Niels K. Handest
using System;
using System.Collections;

namespace HugeInt
{
    public struct HugeInt
    {
        // Each "digit" is porebtioly in range 0-18.446.744.073.709.551.615 = 0 - 2^64-1.
        private ulong[] Digit;

        // However, I'm restricting to the subrabge 0-999.999.999 since this ensures that
        // Digit*Digit is also within ulong-range.
        private const byte CiffersPerDigit = 9;
        private static readonly ulong Radix = (ulong) Math.Pow(10, CiffersPerDigit);

        public HugeInt(string AsString)
        {
            ArrayList ProtoDigit = new ArrayList();

            while (AsString != "")
            {
                int Pos = AsString.Length - CiffersPerDigit;
                if (Pos < 0) Pos = 0;

                int Len = CiffersPerDigit;
                if (AsString.Length < Len) Len = AsString.Length;

                string ProtoDigitStr = AsString.Substring(Pos, Len);
                ProtoDigit.Add(ulong.Parse(ProtoDigitStr));

                AsString = AsString.Substring(0, Pos);               
            }

            int NoOfDigits = ProtoDigit.Count;
            Digit = new ulong[NoOfDigits];
            ProtoDigit.CopyTo(Digit);
        }

        public override string ToString()
        {
            int Len = Digit.Length;

            string Result = Digit[Len-1].ToString();

            for (int i=Len-2; i>=0; i--)
                Result += Digit[i].ToString().PadLeft(CiffersPerDigit, '0');

            return Result;
        }

        public static HugeInt operator +(HugeInt A, HugeInt B)
        {
            ArrayList TempDigit = new ArrayList();

            int Len = Math.Max(A.Digit.Length, B.Digit.Length);

            ulong Carry = 0;
            for (int Idx=0; Idx<Len; Idx++)
            {
                ulong ADigit = (Idx<A.Digit.Length) ? A.Digit[Idx] : 0;
                ulong BDigit = (Idx<B.Digit.Length) ? B.Digit[Idx] : 0;

                ulong CDigit = checked(Carry + ADigit + BDigit);
                Carry = CDigit / Radix;
                CDigit = CDigit % Radix;

                TempDigit.Add(CDigit);
            }
            if (Carry > 0) TempDigit.Add(Carry);

            HugeInt Result = new HugeInt();
            Result.Digit = new ulong[TempDigit.Count];
            TempDigit.CopyTo(Result.Digit);

            return Result;
        }

        public static HugeInt operator <<(HugeInt A, int B)
        {
            ArrayList TempDigit = new ArrayList();

            for (int Idx=1; Idx<=B; Idx++)
                TempDigit.Add((ulong)0);

            for (int AIdx=0; AIdx<A.Digit.Length; AIdx++)
                TempDigit.Add(A.Digit[AIdx]);

            HugeInt Result = new HugeInt();
            Result.Digit = new ulong[TempDigit.Count];
            TempDigit.CopyTo(Result.Digit);

            return Result;
        }

        public static HugeInt operator *(HugeInt A, ulong B)
        {
            if (B >= Radix)
                throw new System.ArgumentOutOfRangeException("Faxtor should be less than " + Radix);

            ArrayList TempDigit = new ArrayList();

            ulong Carry = 0;
            for (int AIdx=0; AIdx<A.Digit.Length; AIdx++)
            {
                ulong ADigit = A.Digit[AIdx];

                ulong CDigit = checked(Carry + ADigit*B);
                Carry = CDigit / Radix;
                CDigit = CDigit % Radix;

                TempDigit.Add(CDigit);
            }
            if (Carry > 0) TempDigit.Add(Carry);

            HugeInt Result = new HugeInt();
            Result.Digit = new ulong[TempDigit.Count];
            TempDigit.CopyTo(Result.Digit);

            return Result;
        }

        public static HugeInt operator *(HugeInt A, HugeInt B)
        {
            HugeInt Result = new HugeInt("");

            for (int AIdx=0; AIdx<A.Digit.Length; AIdx++)
            {
                ulong ADigit = A.Digit[AIdx];

                Result += (B<<AIdx) * ADigit;
            }

            return Result;
        }
    }
}
Avatar billede nielle Nybegynder
16. april 2005 - 20:52 #5
Udregning af 1000!

            HugeInt Frak = new HugeInt("1");  // 0! = 1

            for (int i=1; i<=1000; i++)
            {
                Frak *= (ulong)i;
                Console.WriteLine("{0}: {1}", i, Frak);
            }
Avatar billede nielle Nybegynder
16. april 2005 - 20:52 #6
Udregning af 2^1000

            HugeInt Pow = new HugeInt("1");

            for (int i=1; i<=30; i++)
            {
                Pow *= 2;
                Console.WriteLine("{0}: {1}", i, Pow);
            }
Avatar billede nielle Nybegynder
20. april 2005 - 14:33 #7
fanatic> Var det det du skulle bruge, eller hvad?
Avatar billede nielle Nybegynder
02. maj 2005 - 21:38 #8
Eftersom at vi har brugt tid på dit spørgsmål kunne du i det mindste reagere.
Avatar billede fanatic Nybegynder
02. maj 2005 - 22:44 #9
niele>> JA!! Jeg takker mange gange for hjælpen. Send et svar ellers kan jeg jo ikke give dig point ;-)
Avatar billede nielle Nybegynder
02. maj 2005 - 23:01 #10
Svar :^)

Du har ikke brug for at kunne dividere og subtrahere?
Avatar billede nielle Nybegynder
09. maj 2005 - 10:03 #11
?
Avatar billede fanatic Nybegynder
18. maj 2005 - 08:38 #12
Nej....problemet er løst. Mange tak for hjælpen ;-)
Avatar billede nielle Nybegynder
18. maj 2005 - 18:12 #13
Selv tak. :^)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester