2010-12-04 7 views
0

Ich testen BigIntegers.Arbeiten mit BigIntegers in C#

Wenn ich eine große ungerade Zahl nehme und sie durch 2 dividiere, bekomme ich eine ganze Zahl als Antwort, ohne irgendeinen Hinweis, dass sie die Zahl nicht genau teilen könnte.

Also erste Frage ist, woher weiß ich, dass zwei Zahlen genau teilen.

Getestet habe ich es dann mit einer kleinen Zahl, einen diesen Code:

 string myNumberAsString = "25"; 
     System.Text.UTF8Encoding encoding=new System.Text.UTF8Encoding(); 
     byte[] myNumberAsByteArray = encoding.GetBytes(myNumberAsString); 
     BigInteger myNumber = new BigInteger(myNumberAsByteArray); 
     Console.WriteLine(myNumber/2); 

das Ergebnis Gibt 6809. Jeder weiß, warum oder sehen kann, was mit meinem Code falsch?

Ich bin mit der .net 4.0 Implementierung von BigInteger

+0

Ich glaube nicht, dass die Codierung zu UTF8 Ihnen ein Byte-Array gibt, das die Zahl 25 darstellt? – flq

+2

6809 in hex ist 0x1A99, was genau die Hälfte von 0x3532 ist. Die ASCII-Codes (UTF-8 verwendet ASCII-Codes für Zeichen im ASCII-Bereich) für die Zeichen in Ihrer Zeichenfolge sind 0x32 und 0x35, die aufgrund der Little-Endian-Byte-Reihenfolge 0x3532 werden. Ihre "große Ganzzahl" ist also nicht ungerade und die Division gibt Ihnen das richtige Ergebnis. –

Antwort

3

Abgesehen von den String-to-BigInteger-Konvertierungsproblemen, auf die andere hingewiesen haben, ergibt die Division von zwei BigIntegern immer ein BigInteger-Ergebnis (da Integer keine gebrochene Komponente haben). Dieses Ergebnis ist der ganzzahlige Teil dessen, was das Fließkommaergebnis gewesen wäre.

Um zu bestimmen, ob die Aufteilung genau war oder nicht, verwenden Sie die DivRem() Methode:

var dividend = BigInteger.Parse("25"); 

BigInteger remainder; 
var quotient = BigInteger.DivRem(dividend, 2, out remainder); 
if (!remainder.IsZero) { 
    throw new Exception("Division resulted in remainder of " + remainder + "!"); 
} 
3

Ich weiß nicht, was die Umsetzung von BigInteger Sie verwenden aber myNumberAsByteArray nicht den Bytes enthält die Nummer 25 darstellt. Sie konvertieren hier einfach eine Zeichenfolge in Bytes. Sie hätten die Zeichenfolge myNumberAsString = "abc"; verwenden können, die Ihnen ein anderes Ergebnis geliefert hätte.

Sie wollen wahrscheinlich stattdessen die Parse Methode verwenden:

BigInteger myNumber = BigInteger.Parse("25"); 
+2

'BigInteger' ist Teil von System.Numerics seit.Net 4 – Cameron

+1

@Cameron, ich weiß das, aber das OP sollte es angegeben haben. Es gibt auch andere mögliche Implementierungen. –

1

Sie overcomplicating, wie Sie die BigInteger konstruieren - das Framework bietet implizite Abgüsse aus byte, Int16, etc:

BigInteger myNumber = 25; 
Console.WriteLine(myNumber/2); 

Um größere Zahlen aus einer Zeichenfolgendarstellung zu konvertieren, verwenden Sie BigInteger.Parse():

BigInteger myNumber = BigInteger.Parse("252525252525252525252525252525"); 
Console.WriteLine(myNumber/2); 
2

Wenn Sie aus einem String-Darstellung einer Zahl konvertieren müssen, BigInteger.TryParse oder BigInteger.Parse verwenden.

Aber unabhängig davon, wie Sie Ihre BigInteger instanziieren, können Sie bestimmen, ob eine Zahl durch eine andere durch modulare Mathematik teilbar ist. Wenn Sie beispielsweise sehen wollen, ob someNumber durch 2 teilbar ist, dann überprüfen Sie einfach, dass (someNumber % 2) == 0 (d. H. SumNumber/2 hat einen Rest von Null). Dies funktioniert für jeden beliebigen Nenner. Ersetzen Sie einfach 2 mit dem Nenner, den Sie testen möchten. Bei BigInteger sollten Sie jedoch wahrscheinlich die DivRem-Methode anstelle des% -Operators verwenden.

+0

Ich nehme zurück, was ich über DivRem gesagt habe. Das ist nicht wirklich notwendig, aber sicherlich akzeptabel. Der Modulo-Operator (%) ist in Ordnung. Versuchen Sie, implizite Datentypkonvertierungen möglichst zu vermeiden. –