0

I am testing out BigIntegers.

When I take a large odd number and divide it by 2, I get an integer as an anwser, without any indication that it could not divide the number exactly.

So first question is how do I know that two numbers divide exactly.

I then tested it with a small number, an this 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);

Gives the result 6809. Anybody know why or can see what is wrong with my code?

I am using the .net 4.0 implementation of BigInteger

Shiraz Bhaiji
  • 64,065
  • 34
  • 143
  • 252
  • 1
    I don't think that encoding to UTF8 will give you a byte array representing the number 25? – flq Dec 04 '10 at 23:39
  • 2
    6809 in hex is 0x1A99, which is exactly half of 0x3532. The ASCII codes (UTF-8 uses ASCII codes for characters in the ASCII range) for the characters in your string are 0x32 and 0x35, which due to little-endian byte order, become 0x3532. So your "big integer" isn't odd, and division is giving you the correct result. – Ben Voigt Dec 04 '10 at 23:51

4 Answers4

3

I don't know what implementation of BigInteger you are using but myNumberAsByteArray will not contain the bytes representing the number 25. You are simply converting a string to bytes here. You could have used string myNumberAsString = "abc"; which would have given you another result.

You probably want to use the Parse method instead:

BigInteger myNumber = BigInteger.Parse("25");
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
3

Aside from the string-to-BigInteger conversion problems that others have pointed out, dividing two BigIntegers always yields a BigInteger result (since integers don't have a fractional component). This result will be the integer part of whatever the floating-point result would have been.

To determine whether the division was exact or not, use the DivRem() method:

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 + "!");
}
Cameron
  • 96,106
  • 25
  • 196
  • 225
2

If you must convert from a string representation of a number, use BigInteger.TryParse or BigInteger.Parse.

But regardless of how you instantiate your BigInteger, you can determine if a number is evenly divisible by another by using modular math. For example, if you want to see if someNumber is divisible by 2, then just verify that (someNumber % 2) == 0 (i.e., sumNumber / 2 has a remainder of zero). This works for any integer denominator. Just replace 2 with which ever denominator you want to test. With BigInteger, though, you should probably use the DivRem method instead of the % operator.

  • I take back what I said about DivRem. That isn't really necessary, but certainly acceptable. The modulus operator (%) is fine. Just try to avoid implicit data type conversions when possible. – Bradford Hoagland Dec 05 '10 at 00:31
1

You're overcomplicating how you construct the BigInteger - the framework provides implicit casts from byte, Int16, etc:

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

To convert larger numbers from a string representation, use BigInteger.Parse():

BigInteger myNumber = BigInteger.Parse("252525252525252525252525252525");
Console.WriteLine(myNumber / 2);
dahlbyk
  • 75,175
  • 8
  • 100
  • 122