BigInteger FormatException - c#

In my program, I get a FormatException with the message The value could not be parsed on the following line:
c = BigInteger.Parse("" + Math.Pow(b, 3));
The exception occurs when b = 99000, but if I manually replace b with 99000, the exception doesn't occur. I have also tested it with b = 99001, and other higher values but I don't get the error.

The underlying cause is that Math.Pow operates on doubles, not integral data types. By default, Double.ToString() returns only 15 digits of precision, and the double data type can only store a maximum of 17 digits of precision internally.
When b=100,000, b3 = 1,000,000,000,000,000 (16 digits), and the conversion to a string will return the result as 1E+15. BigInteger.Parse can only parse integral values (optional whitespace, followed by a sign, followed by 1 or more numbers), and will throw a FormatException when the string value "1E+15" is provided as an argument.
A solution is to avoid Math.Pow entirely, and to instead use BigInteger.Pow(BigInteger, int). This approach avoids conversions to double entirely, and can exponentiate arbitrarily large integers.
With this change, your code might resemble something like this:
BigInteger c;
for (BigInteger b = 1; b < 1000000; b++)
{
c = BigInteger.Pow(b, 3);
// c stores b^3 as a BigInteger
}

Weird ... This seems to work for me, and you were right about the string in parse.
BigInteger c;
long b = 9000;
c = BigInteger.Parse("" + Math.Pow(b, 3));
No errors thrown ...
As for codemonkeh comment about the ToString(), you could also do this
BigInteger d = new BigInteger(Math.Pow(b, 3));
Assuming you are not running in a loop that will create heaps of those ...

Related

bitwise or a number in int form with a number in hex form

I have a number
int number = 509; // integer
string bool_number = Convert.ToString(number, 2); // same integer converted to binary no
I want to bitwise or this number with hex values 0x01, 0x02, 0x04 and 0x08.
(e.g. something like this)
result = number | 0x01
How can I do it? Should I convert number to hex form or whats the right way?
You can use hexadecimal values as numeric literals...
int number = 509;
int hexNumber = 0x02;
int newNumber = number | hexNumber;
// whatever
string newNumberAsBinaryString = Convert.ToString(newNumber, 2);
Console.WriteLine(newNumber);
// etc.
If you need to input a hex string and convert it to a numeric type:
int num = Int32.Parse(hexString, System.Globalization.NumberStyles.HexNumber);
If you need to output a numeric type as hex:
Console.WriteLine(num.ToString("x"));
// or
Console.WriteLine("{0:x}", num);
See also MSDN's page on dealing with hex strings.
An int value isn't in any particular base. You can use bitwise operators on an int at any time - there's no need to convert it first. For example:
int a = 509;
int b = 0x1fd;
The variables a and b have exactly the same value here. I happen to have used a decimal literal to initialize a, and a hex literal to initialize b, but the effect is precisely the same.
So you can bitwise OR your ints at any time. Your example (adding a suitable declaration and semicolon to make it compile):
int result = number | 0x01;
will work just fine - you don't need to do anything to prepare number for this sort of usage. (Incidentally, this will do nothing, because the result of a bitwise OR of the numbers 509 and 1 is 509. If you write 509 in binary you get 111111101 - the bottom bit is already 1, so ORing in 1 won't change anything.)
You should avoid thinking in terms of things like "hex values", because there isn't really any such thing in C#. Numeric bases are only relevant for numbers represented as strings, which typically means either literals in source code, or conversions done at runtime. For example, if your program accepts a number as a command line argument, then that will arrive as a string, so you'll need to know its base to convert it correctly to an int. But once it's an int it's just an int - there's no such thing as a hex value or a decimal value for an int.

C#: The result of casting a negative integer to a byte

I was a looking at the source code of a project, and I noticed the following statement (both keyByte and codedByte are of type byte):
return (byte)(keyByte - codedByte);
I'm trying now to understand what would the result be in cases where keyByte is smaller than codedByte, which results in a negative integer.
After some experiments to understand the result of casting a negative integer which has a value in the range [-255 : -1], I got the following results:
byte result = (byte) (-6); // result = 250
byte result = (byte) (-50); // result = 206
byte result = (byte) (-17); // result = 239
byte result = (byte) (-20); // result = 236
So, provided that -256 < a < 0 , I was able to determine the result by:
result = 256 + a;
My question is: should I always expect this to be the case?
Yes, that will always be the case (i.e. it is not simply dependent on your environment or compiler, but is defined as part of the C# language spec). See http://msdn.microsoft.com/en-us/library/aa691349(v=vs.71).aspx:
In an unchecked context, the result is truncated by discarding any high-order bits that do not fit in the destination type.
The next question is, if you take away the high-order bits of a negative int between -256 and -1, and read it as a byte, what do you get? This is what you've already discovered through experimentation: it is 256 + x.
Note that endianness does not matter because we're discarding the high-order (or most significant) bits, not the "first" 24 bits. So regardless of which end we took it from, we're left with the least significant byte that made up that int.
Yes. Remember, there's no such thing as "-" in the domain of a .Net "Byte":
http://msdn.microsoft.com/en-us/library/e2ayt412.aspx
Because Byte is an unsigned type, it cannot represent a negative
number. If you use the unary minus (-) operator on an expression that
evaluates to type Byte, Visual Basic converts the expression to Short
first. (Note: substitute any CLR/.Net language for "Visual Basic")
ADDENDUM:
Here's a sample app:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestByte
{
class Program
{
static void Main(string[] args)
{
for (int i = -255; i < 256; i++)
{
byte b = (byte)i;
System.Console.WriteLine("i={0}, b={1}", i, b);
}
}
}
}
And here's the resulting output:
testbyte|more
i=-255, b=1
i=-254, b=2
i=-253, b=3
i=-252, b=4
i=-251, b=5
...
i=-2, b=254
i=-1, b=255
i=0, b=0
i=1, b=1
...
i=254, b=254
i=255, b=255
Here is an algorithm that performs the same logic as casting to byte, to help you understand it:
For positives:
byte bNum = iNum % 256;
For negatives:
byte bNum = 256 + (iNum % 256);
It's like searching for any k which causes x + 255k to be in the range 0 ... 255. There could only be one k which produces a result with that range, and the result will be the result of casting to byte.
Another way of looking at it is as if it "cycles around the byte value range":
Lets use the iNum = -712 again, and define a bNum = 0.
We shall do iNum++; bNum--; untill iNum == 0:
iNum = -712;
bNum = 0;
iNum++; // -711
bNum--; // 255 (cycles to the maximum value)
iNum++; // -710
bNum--; // 254
... // And so on, as if the iNum value is being *consumed* within the byte value range cycle.
This is, of course, just an illustration to see how logically it works.
This is what happens in unchecked context. You could say that the runtime (or compiler if the Int32 that you cast to Byte is known at compiletime) adds or subtracts 256 as many times as is needed until it finds a representable value.
In a checked context, an exception (or compiletime error) results. See http://msdn.microsoft.com/en-us/library/khy08726.aspx
Yes - unless you get an exception.
.NET defines all arithmetic operations only on 4 byte and larger data types. So the only non-obvious point is how converting an int to a byte works.
For a conversion from an integral type to another integral type, the result of conversion depends on overflow checking context (says the ECMA 334 standard, Section 13.2.1).
So, in the following context
checked
{
return (byte)(keyByte - codedByte);
}
you will see a System.OverflowException. Whereas in the following context:
unchecked
{
return (byte)(keyByte - codedByte);
}
you are guaranteed to always see the results that you expect regardless of whether you do or don't add a multiple of 256 to the difference; for example, 2 - 255 = 3.
This is true regardless of how the hardware represents signed values. The CLR standard (ECMA 335) specifies, in Section 12.1, that the Int32 type is a "32-bit two's-complement signed value". (Well, that also matches all platforms on which .NET or mono is currently available anyway, so one could almost guess that it would work anyway, but it is good to know that the practice is supported by the language standard and portable.)
Some teams do not want to specify overflow checking contexts explicitly, because they have a policy of checking for overflows early in development cycle, but not in released code. In these cases you can safely do byte arithmetic like this:
return (byte)((keyByte - codedByte) % 256);

I need to take an int and convert it into its binary notation (C#)

I need to take an int and turn it into its byte form.
i.e. I need to take '1' and turn it into '00000001'
or '160' and turn it into '10100000'
Currently, I am using this
int x = 3;
string s = Convert.ToString(x, 2);
int b = int.Parse(s);
This is an awful way to do things, so I am looking for a better way.
Any Suggestions?
EDIT
Basically, I need to get a list of every number up to 256 in base-2. I'm going to store all the numbers in a list, and keep them in a table on my db.
UPDATE
I decided to keep the base-2 number as a string instead of parsing it back. Thanks for the help and sorry for the confusion!
If you need the byte form you should take a look at the BitConverter.GetBytes() method. It does not return a string, but an array of bytes.
The int is already a binary number. What exactly are you looking to do with the new integer? What you are doing is setting a base 10 number to a base 2 value. That's kind of confusing and I think you must be trying to do something that should happen a different way.
I don't know what you need at the end ... this may help:
Turn the int into an int array:
byte[] bytes = BitConverter.GetBytes(x);
Turn the int into a bit array:
BitArray bitArray = new BitArray(new[] {x});
You can use BitArray.
The code looks a bit clumsy, but that could be improved a bit.
int testValue = 160;
System.Collections.BitArray bitarray = new System.Collections.BitArray(new int[] { testValue });
var bitList = new List<bool>();
foreach (bool bit in bitarray)
bitList.Add(bit);
bitList.Reverse();
var base2 = 0;
foreach (bool bit in bitList)
{
base2 *= 10; // Shift one step left
if (bit)
base2++; // Add 1 last
}
Console.WriteLine(base2);
I think you are confusing the data type Integer with its textual representation.
int x = 3;
is the number three regardless of the representation (binary, decimal, hexadecimal, etc.)
When you parse the binary textual representation of an integer back to integer you are getting a different number. The framework assumes you are parsing the number represented in the decimal base and gives the corresponding integer.
You can try
int x = 1600;
string s = Convert.ToString(x, 2);
int b = int.Parse(s);
and it will throw an exception because the binary representation of 1600 interpreted as decimal
is too big to fit in an integer

Best way to get whole number part of a Decimal number

What is the best way to return the whole number part of a decimal (in c#)? (This has to work for very large numbers that may not fit into an int).
GetIntPart(343564564.4342) >> 343564564
GetIntPart(-323489.32) >> -323489
GetIntPart(324) >> 324
The purpose of this is: I am inserting into a decimal (30,4) field in the db, and want to ensure that I do not try to insert a number than is too long for the field. Determining the length of the whole number part of the decimal is part of this operation.
By the way guys, (int)Decimal.MaxValue will overflow. You can't get the "int" part of a decimal because the decimal is too friggen big to put in the int box. Just checked... its even too big for a long (Int64).
If you want the bit of a Decimal value to the LEFT of the dot, you need to do this:
Math.Truncate(number)
and return the value as... A DECIMAL or a DOUBLE.
edit: Truncate is definitely the correct function!
I think System.Math.Truncate is what you're looking for.
Depends on what you're doing.
For instance:
//bankers' rounding - midpoint goes to nearest even
GetIntPart(2.5) >> 2
GetIntPart(5.5) >> 6
GetIntPart(-6.5) >> -6
or
//arithmetic rounding - midpoint goes away from zero
GetIntPart(2.5) >> 3
GetIntPart(5.5) >> 6
GetIntPart(-6.5) >> -7
The default is always the former, which can be a surprise but makes very good sense.
Your explicit cast will do:
int intPart = (int)343564564.5
// intPart will be 343564564
int intPart = (int)343564565.5
// intPart will be 343564566
From the way you've worded the question it sounds like this isn't what you want - you want to floor it every time.
I would do:
Math.Floor(Math.Abs(number));
Also check the size of your decimal - they can be quite big, so you may need to use a long.
You just need to cast it, as such:
int intPart = (int)343564564.4342
If you still want to use it as a decimal in later calculations, then Math.Truncate (or possibly Math.Floor if you want a certain behaviour for negative numbers) is the function you want.
I hope help you.
/// <summary>
/// Get the integer part of any decimal number passed trough a string
/// </summary>
/// <param name="decimalNumber">String passed</param>
/// <returns>teh integer part , 0 in case of error</returns>
private int GetIntPart(String decimalNumber)
{
if(!Decimal.TryParse(decimalNumber, NumberStyles.Any , new CultureInfo("en-US"), out decimal dn))
{
MessageBox.Show("String " + decimalNumber + " is not in corret format", "GetIntPart", MessageBoxButtons.OK, MessageBoxIcon.Error);
return default(int);
}
return Convert.ToInt32(Decimal.Truncate(dn));
}
Very easy way to separate value and its fractional part value.
double d = 3.5;
int i = (int)d;
string s = d.ToString();
s = s.Replace(i + ".", "");
s is fractional part = 5 and
i is value as integer = 3
Public Function getWholeNumber(number As Decimal) As Integer
Dim round = Math.Round(number, 0)
If round > number Then
Return round - 1
Else
Return round
End If
End Function
Forgetting the meaning of the term: "Whole Number" seems common in the answers, and in the Question.
Getting the whole number from the number: 4 is simple:
1 x 4 = 4 <- A Whole Number! The first Whole Number!
2 x 4 = 8 <- A Whole Number!
3 x 4 = 12 <- A Whole Number!
Rounding a Number, to get a Whole Number is a cheats method of getting the Whole Numbers! Rounding it removing the Non-Whole Number part of the Number!
1.3 x 4 = 5.2 <- NOT a Whole Number!
1 x 343564564.4342 <- NOT a Whole Number!
Its important to understand what a Whole Number is!
4 / 1 = 4 <- A Whole Number!
4 / 2 = 2 <- A Whole Number!
4 / 3 = 1.333 recurring <- NOT A Whole Number!
Please ask, and answer the questions with a bit more Accuracy Peeps...
double A = Math.Abs(343564564.4342);
double B = Math.Floor(343564564.4342);
double C = Math.Ceiling(343564564.4342);
double D = Math.Truncate(343564564.4342);
Returns:
A = 343564564.4342
B = 343564564
C = 343564565
D = 343564564
or:
double E = Math.Round(343564564.4342, 0);
E = 343564564
Is a Mathematical Function, thus changing the Number, and not working with Whole Numbers. Your Rounding Non-Whole Numbers!

How can I Convert a Big decimal number to Hex in C# (Eg : 588063595292424954445828)

The number is bigger than int & long but can be accomodated in Decimal. But the normal ToString or Convert methods don't work on Decimal.
I believe this will produce the right results where it returns anything, but may reject valid integers. I dare say that can be worked around with a bit of effort though... (Oh, and it will also fail for negative numbers at the moment.)
static string ConvertToHex(decimal d)
{
int[] bits = decimal.GetBits(d);
if (bits[3] != 0) // Sign and exponent
{
throw new ArgumentException();
}
return string.Format("{0:x8}{1:x8}{2:x8}",
(uint)bits[2], (uint)bits[1], (uint)bits[0]);
}
Do it manually!
http://www.permadi.com/tutorial/numDecToHex/
I've got to agree with James - do it manually - but don't use base-16. Use base 2^32, and print 8 hex digits at a time.
I guess one option would be to keep taking chunks off it, and converting individual chunks? A bit of mod/division etc, converting individual fragments...
So: what hex value do you expect?
Here's two approaches... one uses the binary structure of decimal; one does it manually. In reality, you might want to have a test: if bits[3] is zero, do it the quick way, otherwise do it manually.
decimal d = 588063595292424954445828M;
int[] bits = decimal.GetBits(d);
if (bits[3] != 0) throw new InvalidOperationException("Only +ve integers supported!");
string s = Convert.ToString(bits[2], 16).PadLeft(8,'0') // high
+ Convert.ToString(bits[1], 16).PadLeft(8, '0') // middle
+ Convert.ToString(bits[0], 16).PadLeft(8, '0'); // low
Console.WriteLine(s);
/* or Jon's much tidier: string.Format("{0:x8}{1:x8}{2:x8}",
(uint)bits[2], (uint)bits[1], (uint)bits[0]); */
const decimal chunk = (decimal)(1 << 16);
StringBuilder sb = new StringBuilder();
while (d > 0)
{
int fragment = (int) (d % chunk);
sb.Insert(0, Convert.ToString(fragment, 16).PadLeft(4, '0'));
d -= fragment;
d /= chunk;
}
Console.WriteLine(sb);

Categories