-
December 6th, 2011, 04:42 AM
#1
Cleanest way to check if a number is an integer.
So I need to find factors of my numbers to speed up my algorithm and I'm dividing by prime factors and to find them I obviously need to know if they are still integers after I divide into each prime. For 2 and 3 this is easy, since I can do simple bit operations before I divide. For any prime | prime > 3, I want to do a brute force approach and check if my result is an integer or a fraction.
I thought about this and I could use %, if % > 0, I have a fraction.
I could put the result in an integer and in a float, if float and integer differ, I have a fraction.
I could simply use a float, do a bit operation on the exponent part (bits 2-9 iirc) to see if the float has a decimal.
I could use Math.Truncate(double) from the .Net library which takes out the integer part for me, if I check thsi against the double and if it's not 0, I have a fraction.
Which method would you use?
Last edited by Candystore; December 6th, 2011 at 04:50 AM.
-
December 6th, 2011, 07:30 AM
#2
Re: Cleanest way to check if a number is an integer.
What about
Code:
bool isNotInteger = (number > (float)((int)number);
You'd be casting the number to integer (removing fractions), then back to float to have the same data type for comparing. If your original number is greater than your truncated one, you have a fraction.
Would that work?
-
December 6th, 2011, 07:53 AM
#3
Re: Cleanest way to check if a number is an integer.
Originally Posted by Nikel
What about
Code:
bool isNotInteger = (number > (float)((int)number);
You'd be casting the number to integer (removing fractions), then back to float to have the same data type for comparing. If your original number is greater than your truncated one, you have a fraction.
Would that work?
Converting a float to integer and then back to float is going to be very detrimental to performance. You are going to encounter a significant load-hit-store penalty. You should generally avoid casting floats <--> ints whenever possible.
You could try one of these two solutions:
Code:
bool isInteger(float num)
{
return num % 1 == 0;
}
bool isInteger(float num)
{
return (float)Math.Floor(num) == num;
}
I suspect the Math.Floor version will perform better, but you should check yourself.
-
December 6th, 2011, 08:00 AM
#4
Re: Cleanest way to check if a number is an integer.
Thank you. I will try Nikel.
I used bit checking before you replied and it seems to be working, although someone said it doesn't for some negative number (I don't know why he said that at all), and he recommended % modulus.
this is my bit checker for factors of 2 (even)
Code:
while ((number & 1) == 0)
{
number = number / 2;
counterOf2 = counterOf2 + 1;
}
I'm using a class that reads the next prime number from a text file and does a "%" for all primes > 2 atm.
Seems to work ok in a small test, it's spitting out the right factors.
-
December 6th, 2011, 08:02 AM
#5
Re: Cleanest way to check if a number is an integer.
Thank you Chris also, I will check that.
-
December 6th, 2011, 09:09 AM
#6
Re: Cleanest way to check if a number is an integer.
Only use floating point numbers if you're ok with the inaccuracy they will give you. You will get false positives and negatives for certain number combinations. If you want accuracy you should use the modulus operator to see if the number is exactly divisible.
www.monotorrent.com For all your .NET bittorrent needs
NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.
-
December 7th, 2011, 12:08 AM
#7
Re: Cleanest way to check if a number is an integer.
Sorry, but do I understand the problem correctly: you have an integer you wish to factorize?
The best way to avoid all of this (which I think MutantFruit is trying to point out) is to not use floats and just stick with integers:
Code:
//Naive method: requires knownPrimes to contain all primes up to sqrt(number) + 1
//For number=12 this method should return a list: { 2, 2, 3}
List<int> factorize(int number, List<int> knownPrimes)
{
//The maximum factor of a number is given by it's square root (+1 to avoid an off by one error)
int maxFactor = (int)Math.sqrt(number) + 1;
List<int> factors = new List<int>();
for(int i = 0; i < knownPrimes.Count && number != 1; i++)
{
if( knownPrimes[i] > maxFactor)
break;
//While the prime is a factor...
while( number % knownPrimes[i] == 0 )
{
factors.Add(knownPrimes[i]);
number /= knownPrimes[i];
}
}
//Add any non-one value in number (which must be prime)
if( number != 1 )
factors.Add(number);
}
The only place I used a float (actually a double) was in the sqrt call, but it's only to immediately approximate an integer that slightly overestimates the true square, so no need for any sort of precision.
Last edited by BioPhysEngr; December 7th, 2011 at 12:12 AM.
Best Regards,
BioPhysEngr
http://blog.biophysengr.net
--
All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|