The problem I am trying to solve is to find the primality of an arbitrarily long number (BigInteger) in C#. To achieve this task, I have implemented the "Sieve of Erathostenes". The algorithm is already fast, but in terms of accuracy, I am skeptical as I am unsure of how accurate BigInteger is in representing arbitrarily long numbers.
The "Sieve of Erathostenes" algorithm
public static bool IsPrime(BigInteger value)
{
int result = 0;
// 2, 3, 5 and 7 are the base primes used in the Sieve of Erathostenes
foreach (int prime in new int[] { 2, 3, 5, 7 })
{
// If the value is the base prime, it's prime - no further calculation required.
if (value == prime)
{
return true;
}
// Else, we need to work out if the value is divisible, by any of these primes...
BigInteger remainder = 0;
BigInteger.DivRem(value, prime, out remainder);
if (remainder != 0)
{
// We increment result to indicate that the value was not divisible by the base prime
result++;
}
}
// If result is 4, thus, not divisible my any of the base primes, it must be prime.
return result == 4;
}
My question is not "why is my code not working" - it's more "is this accurately determining primality of BigInteger"
Specifically, I would like to know about the accuracy of BigInteger.DivRem
Sieve of Erathostenes is work as follow:
First assume that all numbers is prime.
Starting from 2, crossing out all the numbers that is a multiple of two. Then, move to the next number that is not crossed out, and remove all multiple of this number, and so on... so, in the end what is left is the list of prime number.
So clearly, your code is not Sieve of Erathostenes, which you made an assumption that the list of prime is only 2,3,5,7
To check whether a number is a prime or not, we can have a more easy way, instead of using Sieve of Erathostenes, which is only suitable when you want to generate a list of prime numbers.
Pseudo Code:
boolean isPrime(int num){
for(int i = 2; i*i <= num ; i++){
if(num % i == 0){
return false;
}
}
return true;
}
Related
I know to change the value in nested for loop i=2 the program will not give result in prime numbers. But I want to know the reason and purpose of assigning only 2 to i. Also a Plus if someone explain this using pseudo code.
using System;
namespace Prime_number
{
class Program
{
static void Main(string[] args)
{
int num, i, count, start, end;
Console.Write("Enter Start of range: ");
start = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter End of range : ");
end = Convert.ToInt32(Console.ReadLine());
Console.Write("The prime numbers between {0} and {1} are : \n", start, end);
for (num = start; num <= end; num++)
{
count = 0;
for (i = 2; i <= num / 2; i++)
{
if (num % i == 0)
{
count++;
break;
}
}
if (count == 0 && num != 1)
Console.Write(num + "\n");
}
Console.Write("\n");
}
}
}
It is a self explanatory code:
Read the range_start value.
Read the range_end value.
For each value from range_start to range_end
Check if valueis divisible by any number in range 2 to the half of value
It will be prime if it is not divisible.
The divisors 0 and 1 are not tested for obvious reasons, all numbers are divisible by 1 and any number divided by 0 gives same result, infinity, in limits theory, or divide by zero exception, in a real CPU implementation. only numbers up to value / 2 are tested for an also obvious reason, value would not be divisible by any number in that range but itself.
EDIT: As you're working with integer values, one small optimization would be to use value >> 1 instead of value / 2, shift operations are way faster than div operations at CPU level, yet compilers often apply this optimization when the divisor is known at compile-time.
What is the fastest way to find if a number is even or odd?
It is pretty well known that
static inline int is_odd_A(int x) { return x & 1; }
is more efficient than
static inline int is_odd_B(int x) { return x % 2; }
But with the optimizer on, will is_odd_B be no different from is_odd_A? No — with gcc-4.2 -O2, we get, (in ARM assembly):
_is_odd_A:
and r0, r0, #1
bx lr
_is_odd_B:
mov r3, r0, lsr #31
add r0, r0, r3
and r0, r0, #1
rsb r0, r3, r0
bx lr
We see that is_odd_B takes 3 more instructions than is_odd_A, the main reason is because
((-1) % 2) == -1
((-1) & 1) == 1
However, all the following versions will generate the same code as is_odd_A:
#include <stdbool.h>
static inline bool is_odd_D(int x) { return x % 2; } // note the bool
static inline int is_odd_E(int x) { return x % 2 != 0; } // note the !=
What does this mean? The optimizer is usually sophisticated enough that, for these simple stuff, the clearest code is enough to guarantee best efficiency.
Usual way to do it:
int number = ...;
if(number % 2) { odd }
else { even }
Alternative:
int number = ...;
if(number & 1) { odd }
else { even }
Tested on GCC 3.3.1 and 4.3.2, both have about the same speed (without compiler optimization) as both result in the and instruction (compiled on x86) - I know that using the div instruction for modulo would be much slower, thus I didn't test it at all.
if (x & 1) is true then it's odd, otherwise it's even.
bool is_odd = number & 1;
int i=5;
if ( i%2 == 0 )
{
// Even
} else {
// Odd
}
int is_odd(int n)
{
if (n == 0)
return 0;
else if (n == 1)
return 1;
else
return !is_odd(n - 1);
}
Oh wait, you said fastest way, not funniest. My bad ;)
Above function only works for positive numbers of course.
Check to see if the last bit is 1.
int is_odd(int num) {
return num & 1;
}
If it's an integer, probably by just checking the least significant bit. Zero would be counted as even though.
The portable way is to use the modulus operator %:
if (x % 2 == 0) // number is even
If you know that you're only ever going to run on two's complement architectures, you can use a bitwise and:
if (x & 0x01 == 0) // number is even
Using the modulus operator can result in slower code relative to the bitwise and; however, I'd stick with it unless all of the following are true:
You are failing to meet a hard performance requirement;
You are executing x % 2 a lot (say in a tight loop that's being executed thousands of times);
Profiling indicates that usage of the mod operator is the bottleneck;
Profiling also indicates that using the bitwise-and relieves the bottleneck and allows you to meet the performance requirement.
Your question is not completely specified. Regardless, the answer is dependent on your compiler and the architecture of your machine. For example, are you on a machine using one's complement or two's complement signed number representations?
I write my code to be correct first, clear second, concise third and fast last. Therefore, I would code this routine as follows:
/* returns 0 if odd, 1 if even */
/* can use bool in C99 */
int IsEven(int n) {
return n % 2 == 0;
}
This method is correct, it more clearly expresses the intent than testing the LSB, it's concise and, believe it or not, it is blazing fast. If and only if profiling told me that this method were a bottleneck in my application would I consider deviating from it.
Check the least significant bit:
if (number & 0x01) {
// It's odd
} else {
// It's even
}
Can't you just look at the last digit and check if its even or odd if the input is in base 10?
{1, 3, 5, 7, 9} is odd
{0, 2, 4, 6, 8} is even
Additional info: The OP states that a number is a given, so I went with that when constructing this answer. This also requires the number to be in base 10. This answer is mathematically correct by definition of even/odd in base 10. Depending on the use case, you have a mathematically consistent result just by checking the last digit.
Note: If your input is already an int, just check the low bit of that. This answer is only useful for numbers represented as a sequence of digits. You could convert int->string to do this, but that would be much slower than n % 2 == 0.
Checking the last digit does work for a string of digits in any even base, not just 10. For bases lower than 10, like base 8 (octal), 9 and 8 aren't possible digits, but the low digit being odd or even still determines whether the whole number is.
For bases higher than 10, there will be extra possibilities, but you don't want to search a list anyway, just check if the digit as an integer is odd or even using the normal i % 2 == 0 or !=0 check.
For ASCII hex using 'a' .. 'f' to represent digits values 10 through 15, the low bit of ASCII code does not represent odd or even, because 'a' == 0x61 (odd) but represents 10 aka 0xa (even). So you'd have to convert the hex digit to an integer, or do some bit-hack on the ASCII code to flip the low bit according to some other bit or condition.
i've write this piece of code to check if a number is prime or not, but it doesen't work, I mean that the output is:
1 isn't a prime number
2 is a prime number
3 isn't a prime number
4 is a prime number etc.
please can you tell me what are my mistakes,
thanks
p.s. i've writenumber =1 because i can't divide a number for 0.
for( int number =1;number <101 && number >0;number++)
{
int reimander = (number / 1) & (number / number);
Console.WriteLine(number +(reimander == 0 ? " is a prime number" : " isn't a prime number"));
}
As mentioned Daisy Shipton, your checkings are not sufficient to determine if your number is prime.
In order for a number to be prime, it has to be only divisible by one or itself.
That mean you should check the division by every single numbers between 3 and the number which you are checking the fact of behing prime.
In reality, you don't need to check every numbers between 3 and your number but only the ones between 3 and the square of your number.
In fact, if a whole number k is composite (non prime), it can be written as the product of two whole numbers p and q : k = p*q
Howevern those two numbers p and q can't be simultaneously greater than the square (s) of k, because in this case, their product whould be greater than k.
if p > s and q > s, then p x q > s x s, that to say p x q > k.
The code should looks like something like that (not tested) :
public static bool IsPrime(int number)
{
/****** easy check before going to long calculations *******/
if (number < 2) return false; // A prime number is always greater than 1
if (number == 2) return true; // 2 is prime
if (number % 2 == 0) return false; // Even numbers except 2 are not prime
/****** if your number is Odd and not equals to 2,
you have to check every numbers between 3
and the square of your number *******/
var boundary = (int)Math.Floor(Math.Sqrt(number)); // square of your number
// increment i by 2 because you already checked that your number is Odd
// and therefore not divisible by an Even number
for (int i = 3; i <= boundary; i += 2)
{
if (number % i == 0) return false; // the number can be devided by an other => COMPOSITE number
}
return true; // number at least equals to 3, divisible only by one or itself => PRIME number
}
Now you could do a basic loop for each numbers you want to test and call this function of them. Their is a lot of methods to calculate a series of prime numbers but their are also much more complicated to understand.
for (int number = 1; number < 101 && number > 0; number++)
{
Console.WriteLine(number + " is " + (IsPrime(number) ? "prime" : "not prime"));
}
There are two sorts of problem here: the is-prime algorithm and the C# syntax.
To understand the algorithm for whether a number is prime, search math sites online. For example, here.
Once you know how the math works, you can convert it into code. Based on the code you already have, you should learn the difference between & and && and how to get a remainder.
I have a for loop such as:
for (int indexCount = 2, thirdNumber.ToString().Length!=1000; indexCount++)
I want the loop to terminate when there are 1000 digits in thirdNumber. How can I do this?
It's not possible to have an int with 1000 digits. The maximum int value is 2,147,483,647, which is only 10 digits. As far as I'm aware, there are no built-in data types that would represent a number with 1000 digits, or even 100 digits for that matter.
Edit:
A BigInteger can hold an arbitrarily large number (thanks Bradley Uffner). You'll need to add a reference to the System.Numerics assembly. If you use/are using that as your data type, your original comparison of thirdNumber.ToString()!=1000 would be a valid check to see if it is not 1000 digits.
You could also take a more numbers-based approach and compare the BigInteger being checked to the smallest thousand digit number, which is a 1 followed by 999 zeroes. I'm not sure which method would be faster with numbers of this size, though I'd suspect the comparison between two BigIntegers.
class Program
{
static void Main(string[] args)
{
BigInteger minThousandDigits = BigInteger.Parse(new string('9', 999)) + 1;
BigInteger thousandMoreDigits = BigInteger.Parse(new string('5', 1000));
BigInteger notAThousandDigits = BigInteger.Parse(new string('9', 999));
//Displays false
Console.WriteLine($"Is the first number less than a thousand digits? {thousandMoreDigits < minThousandDigits}");
//Displays true
Console.WriteLine($"Is the second number less than a thousand digits? {notAThousandDigits < minThousandDigits}");
Console.ReadLine();
}
}
Use a do loop:
int indexCount = 2;
do
{
// Whatever
indexCount++;
} while (thirdNumber.ToString().Length != 1000);
Note that the loop will always execute at least once in the above example. You can avoid this by using a break statement:
int indexCount = 2;
do
{
if (thirdNumber.ToString().Length == 1000) break;
// Whatever
indexCount++;
} while (true);
The above assumes that length will eventually be equal to 1000, otherwise you'll have an infinite loop.
I need some help with some simple math calculation and the most efficient way to execute them in c#.
10 / 4 = 2.5
How do i determine if the sum is a decimal value and if it is I need to round 4 up to 5 so that it divides into 10 evenly.
Any ideas?
I'm assuming that, given some numbers A and B, you want to find a number x, such that:
x evenly divides A
x is greater than or equal to B
x is minimized
in your given example, A = 10, B = 4, and x = 5.
The simplest-to-code way to find x is:
public int getX(int a, int b){
while(a % b != 0){
b++;
}
return b;
}
Generally speaking, it's not easy to find factors of an arbitrary number. In fact, some computer fields, such as cryptography, depend on the fact that factoring big numbers takes a long time.
That sounds extremely vague. You could figure it out using
if (10%4 != 0) ... //checks if there is a remainder
But how to get it up to 5 would need a lot more context.
Here is my suggestion for a short function doing that:
private int FindCeilingDevider(int numberToDivide, int divisor)
{
double result;
do
{
result = (double) numberToDivide / (double) divisor;
divisor++;
}
while (result != Math.Ceiling(result));
return divisor - 1;
}