I want to return a number that doesn't exceed a limit I set. For example I want to do the equivalent of:
if (number >= limit)
number = limit;
return number;
Is there a mathematical way of doing the equivalent of what I just described in just one line?
You could:
return Math.min(number, limit);
or:
return number >= limit ? limit : number;
There's also the following mathematical formula: (taken from here)
min(a,b) = 1/2 (a + b - |a - b|)
Code:
return ( number + limit - Math.abs(number - limit) ) / 2;
Now Math.abs looks pretty similar to Math.min (so there wouldn't be much point to using the above instead of simply Math.min), although you could easily replace that with the method presented here or here:
mask = n >> 31 // 11111111 for negative and 00000000 for positive
abs = (mask + n)^mask // convert negative to positive in 2's complement
// while not changing positive
Note:
If number + limit can overflow, this won't work. This can be changed to
number - Math.abs(...) + limit to avoid this, but then number - Math.abs(...) can still underflow - you just need to keep overflow in mind and select the option that would prevent over/underflow based on the range of the numbers, or go for the non-arithmetic option.
Also keep in mind that, assuming no over/underflow, if you're dealing with floating point values (float / double) rather than integral types, the result of the above won't necessarily return either of the values (because of the way floating point representation works).
Related
I have a double value which is very close to 1. How can I cast it to 1 ?
I do this
double myValue = 0.9999;
double a = Math.round(myValue);
int intValue = (int)a;
But it return 1 even if myValue is in the the range [0.5 , 1], so I lose precision. I want it return 1 only if myValuse is so close to 1 (exp : 0.999) and it should not return 1 when myValue is 0.6 for example.
Thank u for ur help
Math.round is specifically designed to do that. If you want to do something different, you'll have to code it yourself.
For instance, if you want .8 and higher to round to 1 instead of .5 and higher (see note below about negative numbers):
double myValue = 0.9999;
int base = (int)Math.floor(myValue);
double remainder = myValue - base;
int intValue = remainder >= .8 ? base + 1 : base;
Live Example
There, we:
Get the whole number part (Math.floor) into base, truncating the fractional portion
Get just the fractional portion into remainder
Add one to base if the fractional portion is >= .8
Obviously, you'll have to choose the point at which you round up, since you want something other than .5.
If you want to handle negative numbers, it's more complicated, since Math.floor will always go toward positive infinity. So you may have to branch on the sign of myValue and use Math.ceil instead when negative (and adjust the myValue - base accordingly). And then there's the entire question of whether the same kind of cutoff applies, or is it symmetrical? Should that cutoff be -0.8 or -0.2? I leave handling negative values in the manner you want as an exercise for you...
That said, this feels more complicated than it should be. Perhaps something like what's described in Dawood ibn Kareem's comment would work for what you're trying to do. (May have to be + 0.3 rather than - 0.3 when handling negatives. Or not.)
Try something like:
final double threshold = 0.0001;
if (Math.abs(a - 1) < threshold)
intValue = 1;
else
intValue = 0;
This will set intValue to 1 when a is "close enough to 1" (ie. within threshold of 1), and will set intValue to 0 otherwise (assuming you want it rounded to 0 if it's not within the threshold).
You can adjust the value of the threshold to tighten or loosen the range around 1 that it'll handle.
Alternatively, if you want to round to 1 if it's just above a given value, you can do eg.:
if (a >= 0.9999)
intValue = 1;
else
intValue = 0;
I want to find an effiecient way of making sure that the number of decimal places in
double is not more than three.
double num1 = 10.012; //True
double num2 = 10.2211; //False
double num2 = 10.2; //True
Currently, what I do is just use a regex split and count index of . like below.
String[] split = new Double(num).toString().split("\\.")
split[0].length() //num of decimal places
Is there an efficient or better way to do this since I'll be calling this
function a lot?
If you want a solution that will tell you that information in a way that will agree with the eventual result of converting the double to a string, then efficiency doesn't really come into it; you basically have to convert to string and check. The result is that it's entirely possible for a double to contain a value that mathematically has a (say) non-zero value in (say) the hundred-thousandth place, but which when converted to string will not. Such is the joy of IEEE-754 double-precision binary floating point: The number of digits you get from the string representation is only as many as necessary to distinguish the value from its adjacent representable value. From the Double docs:
How many digits must be printed for the fractional part of m or a? There must be at least one digit to represent the fractional part, and beyond that as many, but only as many, more digits as are needed to uniquely distinguish the argument value from adjacent values of type double. That is, suppose that x is the exact mathematical value represented by the decimal representation produced by this method for a finite nonzero argument d. Then d must be the double value nearest to x; or if two double values are equally close to x, then d must be one of them and the least significant bit of the significand of d must be 0.
But if you're not concerned about that, and assuming limiting your value range to long is okay, you can do something like this:
private static boolean onlyThreePlaces(double v) {
double d = (double)((long)(v * 1000)) / 1000;
return d == v;
}
...which should have less memory overhead than a String-round-trip.
However, I'd be surprised if there weren't a fair number of times when that method and the result of Double.toString(double) didn't match in terms of digits after the decimal, for the reasons given above.
In a comment on the question, you've said (when I asked about the value range):
Honestly I'm not sure. I'm dealing with prices; For starters, I'll assume 0-200K
Using double for financial values is usually not a good idea. If you don't want to use BigDecimal because of memory concerns, pick your precision and use int or long depending on your value range. For instance, if you only need to-the-penny precision, you'd use values multiplied by 100 (e.g., 2000 is Ⓠ20 [or whatever currency you're using, I'm using Ⓠ for quatloos]). If you need precision to thousanths of a penny (as your question suggests), then multiply by 100000 (e.g., 2000000 is Ⓠ20). If you need more precision, pick a larger multiplier. Even if you go to hundred-thousanths of a penny (muliplier: 10000000), with long you have a range of Ⓠ-922,337,203,685 to Ⓠ922,337,203,685.
This has the side-benefit that it makes this check easier: Just a straight %. If your multiplier is 10000000 (hundred-thousandths of a penny), it's just value % 10000 != 0 to identify invalid ones (or value % 10000 == 0 to identify valid ones).
long num1 = 100120000; // 10.012 => true
// 100120000 % 10000 is 0 = valid
long num2 = 102211000; // 10.2211 => false
// 102211000 % 10000 is 1000 = invalid
long num3 = 102000000; // 10.2 => true
// 102000000 % 10000 is 0 = valid
In our code, we have the maximum number of digits allowed (say, 8) in a decimal (as in base 10) number. How can I use this number to see if a possible value is within that range (0 to 99,999,999)?
If we were working with binary numbers, I'd do something like:
value < 1<<(MAX + 1)
but of course that won't work for decimal. I also considered something like:
Long.toString(value).length() < MAX
but that seems much too heavy.
if (value >= 0 && value < Math.pow(10, MAX))
Use log base 10 to get the number of digits in a base 10 number
if ((int)(Math.log10(value) + 1) <= MAX) {
...
}
If you don't have access to log10, you can use normal log to do this:
int length = (int)(Math.log(value) / Math.log(10)) + 1;
if (length <= MAX) {
...
}
Note this also works for any base, so using the second method above, you can replace the 10 with any base and you have the length of that number in the given base
You can take 10 to the (nth) power;
value < (Math.pow (10, num_digits))
… for positive integer fixnums; if you're more concerned with magnitude than sign, perhaps use the absolute value:
Math.abs(value) < (Math.pow (10, num_digits))
This, of course, doesn't apply to floating-point or BigDecimal values, but the same (analogous, using method calls) works for arbitrarily large bignums using BigInteger.
Would this work?
val>=0 && (value/1000000000)==0 ?
I would like to create an integer value between 1 and infinity. I want to have a probability distribution where the smaller the number is, the higher the chance it is generated.
I generate a random value R between 0 and 2.
Take the series
I want to know the smallest m with which my sum is bigger than R.
I need a fast way to determine m. This is would be pretty straightforward if i had R in binary, since m would be equal to the number of 1's my number has in a row from the most significant bit, plus one.
There is an upper limit on the integer this method can generate: integer values have an upper limit and double precision can also only reach so high in the [0;2[ interval. This is irrelevant, however, since it depends on the accuracy of the data representation method.
What would be the fastest way to determine m?
Set up the inequality
R <= 2 - 2**-m
Isolate the term with m
2**-m <= 2 - R
-m <= log2(2-R)
m >= -log2(2-R).
So it looks like you want ceiling(-log2(2-R)). This is basically an exponential distribution with discretization -- the algorithm for an exponential is -ln(1-U)/rate, where U is a Uniform(0,1) and 1/rate is the desired mean.
I think, straightforward solution will be OK as this series converges really fast:
if (r >= 2)
throw new IllegalArgumentException();
double exp2M = 1 / (2 - r);
int x = (int)exp2M;
int ans = 0;
while (x > 0) {
++ans;
x >>= 2;
}
return ans;
I need to do a MOD of a number which is a long datatype with 1965.
Something like this -
number % 1965
Will the above modulus result always be within 0 and 1964?
Or there are some cases in which it won't return any number between 0 and 1664?
I am using Java as programming language and I will be running my program on Ubuntu machines.
Initially I thought its a Math question but it depends mostly on the Compiler and Language... So kind of confused it will always return number between 0 and 1664 or there are some exception cases?
This is what I have in my method -
private static int getPartitionNumber() {
return (int) (number % 1965);
}
UPDATE:
One thing I forgot to mention is, here number will always be positive number. Any negative number I am throwing IllegalArgumentException at the starting of the program.
No, java's implementation of modulus will return a value in the range (-n, n) for the value x % n. I.e. If you have a negative number as the left operand, then the result will be negative. to get around this, try something like the following:
((x % n) + n) % n;
Which will return a value in the range [0,n)
EDIT (to reflect UPDATE in question)
In the case of positive numbers in the left operand, then simply x % n will produce numbers in the range [0,n) where x >= 0.