I am trying to code this in C# but I have problems finding an algorithm to do that.
The goal is to code a function which takes an integer as Parameter and returns an Integerarray (returns 2 integers).
This function should find a valid modulo calculation for the input number which will have as result (reminder) the same number as the input.
For example my Input is the number 5.
Now a valid modulo calculation should be found of which the result is 5.
For example 12 % 7 = 5.
So the function should return 12 and 7.
How can I find the modulo and the divider which will have the same result as the input number?
I cannot show any code because I don't know how I should start of with coding that.
Would be cool of someone can help me out.
think the problem should be:
x%y=z
a) where x,z are knowns y is unknown
instead of
b) where z is known and x,y are unknowns as stated in OP text
anyway for booth cases
the easiest but also the slowest way to compute it is brute-force attack
example a):
const int max=1024; // some solution constraint ...
int imod(int x,int z)
{
if (z==0) return x; // if no remainder then solution is any multiple of x
for (int y=z+1;y<max;y++) if (x%y==z) return y;
return 0; // no solution found
}
y can be anything sufficing condition y > z
that is why start with z+1
example b):
void imod(int &x,int &y,int z)
{
// this is not brute-force because the solution is trivial from the conditions stated in OP
x=z;
y=z+1;
}
no comment needed (all is explained in the comments to your question)
[notes]
code is in C++ so modify it to your language ...
if you need to corelate more numbers to find originally used modulo (crack some code)
then remember all the solutions and choose one common for all numbers
or check all the numbers at once and use only solutions satisfying all the numbers at once
if you have access to original modulo then you can pass incresing numbers to it until it cut off the result value in that case your x>=y so you can recursively find the match in O(log(N)) instead of O(N)...
Step 1. Choose a number, this will be your first output number. Step 2 subtract the input from that number, that will be your other output number
Related
This might not belong here so if I need to ask this somewhere else please tell me.
Let's say we have 10032(Will be X) and 154(Will be Y) as the input, what I would need is to get 1 int as the output. That output would also need to be of length of 4 or 5.
With the output and either X or Y know, I need to stop anyone from discovering the formula. This is a scenario where the Y will stay the same but the X will change often.
I am reading on hash but I am unsure of which one would be the best for me. Or if a simple math formula would do the job. In the program we are currently using it in the following way :
X + Y * 2 / 3 and then rounding to the lower number.
This solution would also need a very low amount of collision.
Thanks
For this question, you may have better luck at Cryptography Stack Exchange but here are a few thoughts.
It sounds like you want to map a 5-digit int and 3-digit int to a 4- or 5-digit int with the qualifications that:
a. The producing algorithm is difficult to determine given the input
b. There are few collisions
Given some function F(x,y) there are 100,000,000 combinations of x and y if x and y are between 1 and 5 digits and 1 and 3 respectively.
If F(x,y) produces a 5-digit number there are 100,000 possible solutions .
On average this would mean that each value of F(x,y) has 1,000 combinations of x, y that map to it.
So at best case this means that given x1, y1 and x2, y2 the odds that F(x1,y1)=F(x2,y2) is 1/1000, which for most uses I can think of would be considered too high.
Considering those things, probably the simplest idea would be a basic modular ring over the ints like Oscar mentioned. For your modulo you should pick the greatest prime number with the number of digits you want to keep. For instance if you want a 5 digit result use 99,877. Or if you wanted to avoid collisions and go with 9-digits, you would use 999,999,733. You can use a prime list to look up which prime you use for your modulo.
I assume that a good approach to minimise collisions would be to use modulus 10^6 after whatever operation you perform on both numbers.
The hard part would be the operation between the original ints, but look up theory about hashing and I am sure you can find nice suggestions.
In order to make it truly difficult to reverse, you could perform operations in several stages, each one of them depending on the results of the previous one. Just an idea...
decimal d = (X * Y) - (reverse X * reverse Y);
(When I say reverse 10032 would be 23001)
Then take the first 4 or 5 digits if there are more.
Or you could make a string that would look like this:
10032154 and then use a Hash method and then take the first 4 or 5 digits?
(You could reverse this too so the string is: 45123001)
BTW why do you need to take the 1st 4 or 5 digits?
Reducing the amount of digits will cause the chance of collusion to increase.
Hi I am currently teaching myself C# using different books and online solutions, there is one exercise that i cant really get my head around. I had to divide a number by another number in C# using iteration and subtraction but the remainder had to be displayed at the end. I figured out that I could use a while loop to keep dividing one number by the other (lets say 400 / 18) but how to display the decimal at the end from the int number was the part I could not get my head around.
Any help would be greatly appriciated :)
So let's think about this outside the C# language. Because this is really just a math problem to solve.
If you've got 400/18, and you are going to use iteration and subtraction, all you are doing is saying "how many times can I subtract 18 from 400?", right?
So that's going to look something like this:
remainder = 400
value = 18
while (remainder > value)
remainder = remainder - value
Once you exit that while loop, you've got your remainder.
You could use the modulus operator "%" to solve this in one step but based on what you wrote, this is what you would do.
The remainder you've got is can be expressed as so:
double theDecimalValue = (double)remainder/value;
Assuming you were dealing with integers, you'd just cast the remainder value to avoid the truncating integer division that will take place otherwise.
if you need the remainder the easy and right way is
int reminder = 400%18;
if you HAVE TO using a loop you have to :
check if number is less than the divisor or whatever it's called
2a.if yes exit from the loop and show the number
2b if not remove divisor from number and go on next iteration
Given that I have two floats, a and b, and only care if they are "approximately equal", would something similar to the following work reliably, or would be it still be subject to precision issues?
eg:
Math.Round(a) == Math.Round(b)
Alternatively, is there a way to reliably round them to the nearest integer? If the above doesn't work, then I assume simply doing (int)Math.Round(a) won't be reliable either.
EDIT: I should have predicted I'd get answers like this, but I'm not trying to determine 'closeness' of the two values. Assuming the logic above is sound, will the above work, or is there a chance that I will get something like 3.0 == 3.0001?
Nothing of this kind will work. There is always a sharp boundary when very similar numbers will be rounded to different numbers.
In your first example think of a=0.4999999 and b=0.5000001. Very close but will round to different integers.
Another problem is that if the numbers are large rounding to an integer will have no effect at all. And even very close(relative) numbers will already an absolute difference >1.
If you care about determinism, you're out of luck with float and double. You just can't get those deterministic on .net. Use Decimal.
IF you really want it reliable then you will have to use Decimal instead of float... although that is much slower...
EDIT:
With ((int)Math.Round(a)) == ((int)Math.Round(b)) you avoid the problem 3.0 == 3.0001 BUT all the other pitfalls mentioned your post and in the answers will still apply...
You can complicate the logic to try to make it a bit more reliable (example see below which could be packaged nicely into some method) but it will never be really reliable...
// 1 = near, 2 = nearer, 3 = even nearer, 4 = nearest
int HowNear = 0;
if (((int)Math.Round(a)) == ((int)Math.Round(b)))
HowNear++;
if (((int)Math.Floor(a)) == ((int)Math.Floor(b)))
HowNear++;
if (((int)Math.Ceiling(a)) == ((int)Math.Ceiling(b)))
HowNear++;
if (Math.Round(a) == Math.Round(b))
HowNear++;
The correct way to convert from double/float to integers is:
(int)Math.Round(a)
having done this you will always get whole numbers which can be tested for equality. If you have numbers which you know are going to be virtually whole numbers (e.g. the result of 6.0/3.0) then this will work great. The recommended way of checking two numbers which are doubles/floats are approximately equal is:
Math.Abs(a-b)<tolerance
where tolerance is a double value that determines how similar they should be, for example, if you want them to be within 1 unit of each other you could use a tolerance of 1.0 which would give you similar accuracy to Math.Round and comparing the results, but is well behaved when you get two values which are very close to half way between two integers.
You could use Floor or Ceieling methods right to rounding of the values.
"approximately equal" is your answer actually, a pseudoexample:
double tollerance = 0.03;
if(Math.Abs(a-b)<=tollerance )
// these numbers are equal !
else
//non equal
EDIT
Or if you want to be more "precise":
int aint = (int)(a*100); // 100 is rounding tollerance
int bint = (int)(b*100); // 100 is rounding tollerance
and after
if(Math.Abs(aint -bint )<=tollerance ) // tollerance has to be integer in this case, obviously
// these numbers are equal !
else
//non equal
I'm trying to determine the number of digits in a c# ulong number, i'm trying to do so using some math logic rather than using ToString().Length. I have not benchmarked the 2 approaches but have seen other posts about using System.Math.Floor(System.Math.Log10(number)) + 1 to determine the number of digits.
Seems to work fine until i transition from 999999999999997 to 999999999999998 at which point, it i start getting an incorrect count.
Has anyone encountered this issue before ?
I have seen similar posts with a Java emphasis # Why log(1000)/log(10) isn't the same as log10(1000)? and also a post # How to get the separate digits of an int number? which indicates how i could possibly achieve the same using the % operator but with a lot more code
Here is the code i used to simulate this
Action<ulong> displayInfo = number =>
Console.WriteLine("{0,-20} {1,-20} {2,-20} {3,-20} {4,-20}",
number,
number.ToString().Length,
System.Math.Log10(number),
System.Math.Floor(System.Math.Log10(number)),
System.Math.Floor(System.Math.Log10(number)) + 1);
Array.ForEach(new ulong[] {
9U,
99U,
999U,
9999U,
99999U,
999999U,
9999999U,
99999999U,
999999999U,
9999999999U,
99999999999U,
999999999999U,
9999999999999U,
99999999999999U,
999999999999999U,
9999999999999999U,
99999999999999999U,
999999999999999999U,
9999999999999999999U}, displayInfo);
Array.ForEach(new ulong[] {
1U,
19U,
199U,
1999U,
19999U,
199999U,
1999999U,
19999999U,
199999999U,
1999999999U,
19999999999U,
199999999999U,
1999999999999U,
19999999999999U,
199999999999999U,
1999999999999999U,
19999999999999999U,
199999999999999999U,
1999999999999999999U
}, displayInfo);
Thanks in advance
Pat
log10 is going to involve floating point conversion - hence the rounding error. The error is pretty small for a double, but is a big deal for an exact integer!
Excluding the .ToString() method and a floating point method, then yes I think you are going to have to use an iterative method but I would use an integer divide rather than a modulo.
Integer divide by 10. Is the result>0? If so iterate around. If not, stop.
The number of digits is the number of iterations required.
Eg. 5 -> 0; 1 iteration = 1 digit.
1234 -> 123 -> 12 -> 1 -> 0; 4 iterations = 4 digits.
I would use ToString().Length unless you know this is going to be called millions of times.
"premature optimization is the root of all evil" - Donald Knuth
From the documentation:
By default, a Double value contains 15
decimal digits of precision, although
a maximum of 17 digits is maintained
internally.
I suspect that you're running into precision limits. Your value of 999,999,999,999,998 probably is at the limit of precision. And since the ulong has to be converted to double before calling Math.Log10, you see this error.
Other answers have posted why this happens.
Here is an example of a fairly quick way to determine the "length" of an integer (some cases excluded). This by itself is not very interesting -- but I include it here because using this method in conjunction with Log10 can get the accuracy "perfect" for the entire range of an unsigned long without requiring a second log invocation.
// the lookup would only be generated once
// and could be a hard-coded array literal
ulong[] lookup = Enumerable.Range(0, 20)
.Select((n) => (ulong)Math.Pow(10, n)).ToArray();
ulong x = 999;
int i = 0;
for (; i < lookup.Length; i++) {
if (lookup[i] > x) {
break;
}
}
// i is length of x "in a base-10 string"
// does not work with "0" or negative numbers
This lookup-table approach can be easily converted to any base. This method should be faster than the iterative divide-by-base approach but profiling is left as an exercise to the reader. (A direct if-then branch broken into "groups" is likely quicker yet, but that's way too much repetitive typing for my tastes.)
Happy coding.
I'm trying to get the number of digits in the following double value: 56.46855976 without using converting it to a string (and simply replacing the "." with a "").
Anybody got any ideas?
Count how often you must divide the number by 10 until it's smaller than 1 -> that gives you the digits before the decimal point.
Then count how often you must multiply the original number by 10 until it equals the Math.Floor-result -> that gives you the digits behind the decimal points.
Add. Be glad.
Edit: As Joey points out, there is some uncertianity in it. Define a maximum number of digits beforehand so you don't create an infinite loop.
On the other hand - "How long is the coast of Denmark?"...
/// Returns how many digits there are to the left of the .
public static int CountDigits(double num) {
int digits = 0;
while (num >= 1) {
digits++;
num /= 10;
}
return digits;
}
As Martin mentioned, counting to the right of the . is pointless.
Tests:
MathPlus.CountDigits(56.46855976) -> 2
MathPlus.CountDigits((double)long.MaxValue + 1) -> 19
MathPlus.CountDigits(double.MaxValue) -> 309
Converting to a string might be the best option you have. Remember that doubles are represented in Base 2 internally. Therefore the decimal representation you see is only an approximation of the actually stored value (except for integers up to 253) which is a sum of individual powers of 2.
So trying to figure out the number of decimal digits from the binary representation is certainly not an easy or trivial task – especially since the framework might also apply rounding to make numbers like 3.999999999998 appear like 4.0 since they appear to have more precision than there actually is.