I have a Java method in which I'm summing a set of numbers. However, I want any negatives numbers to be treated as positives. So (1)+(2)+(1)+(-1) should equal 5.
I'm sure there is very easy way of doing this - I just don't know how.
Just call Math.abs. For example:
int x = Math.abs(-5);
Which will set x to 5.
Note that if you pass Integer.MIN_VALUE, the same value (still negative) will be returned, as the range of int does not allow the positive equivalent to be represented.
The concept you are describing is called "absolute value", and Java has a function called Math.abs to do it for you. Or you could avoid the function call and do it yourself:
number = (number < 0 ? -number : number);
or
if (number < 0)
number = -number;
You're looking for absolute value, mate. Math.abs(-5) returns 5...
Use the abs function:
int sum=0;
for(Integer i : container)
sum+=Math.abs(i);
Try this (the negative in front of the x is valid since it is a unary operator, find more here):
int answer = -x;
With this, you can turn a positive to a negative and a negative to a positive.
However, if you want to only make a negative number positive then try this:
int answer = Math.abs(x);
A little cool math trick! Squaring the number will guarantee a positive value of x^2, and then, taking the square root will get you to the absolute value of x:
int answer = Math.sqrt(Math.pow(x, 2));
Hope it helps! Good Luck!
This code is not safe to be called on positive numbers.
int x = -20
int y = x + (2*(-1*x));
// Therefore y = -20 + (40) = 20
Are you asking about absolute values?
Math.abs(...) is the function you probably want.
You want to wrap each number into Math.abs(). e.g.
System.out.println(Math.abs(-1));
prints out "1".
If you want to avoid writing the Math.-part, you can include the Math util statically. Just write
import static java.lang.Math.abs;
along with your imports, and you can refer to the abs()-function just by writing
System.out.println(abs(-1));
The easiest, if verbose way to do this is to wrap each number in a Math.abs() call, so you would add:
Math.abs(1) + Math.abs(2) + Math.abs(1) + Math.abs(-1)
with logic changes to reflect how your code is structured. Verbose, perhaps, but it does what you want.
When you need to represent a value without the concept of a loss or absence (negative value), that is called "absolute value".
The logic to obtain the absolute value is very simple: "If it's positive, maintain it. If it's negative, negate it".
What this means is that your logic and code should work like the following:
//If value is negative...
if ( value < 0 ) {
//...negate it (make it a negative negative-value, thus a positive value).
value = negate(value);
}
There are 2 ways you can negate a value:
By, well, negating it's value: value = (-value);
By multiplying it by "100% negative", or "-1": value = value *
(-1);
Both are actually two sides of the same coin. It's just that you usually don't remember that value = (-value); is actually value = 1 * (-value);.
Well, as for how you actually do it in Java, it's very simple, because Java already provides a function for that, in the Math class: value = Math.abs(value);
Yes, doing it without Math.abs() is just a line of code with very simple math, but why make your code look ugly? Just use Java's provided Math.abs() function! They provide it for a reason!
If you absolutely need to skip the function, you can use value = (value < 0) ? (-value) : value;, which is simply a more compact version of the code I mentioned in the logic (3rd) section, using the Ternary operator (? :).
Additionally, there might be situations where you want to always represent loss or absence within a function that might receive both positive and negative values.
Instead of doing some complicated check, you can simply get the absolute value, and negate it: negativeValue = (-Math.abs(value));
With that in mind, and considering a case with a sum of multiple numbers such as yours, it would be a nice idea to implement a function:
int getSumOfAllAbsolutes(int[] values){
int total = 0;
for(int i=0; i<values.lenght; i++){
total += Math.abs(values[i]);
}
return total;
}
Depending on the probability you might need related code again, it might also be a good idea to add them to your own "utils" library, splitting such functions into their core components first, and maintaining the final function simply as a nest of calls to the core components' now-split functions:
int[] makeAllAbsolute(int[] values){
//#TIP: You can also make a reference-based version of this function, so that allocating 'absolutes[]' is not needed, thus optimizing.
int[] absolutes = values.clone();
for(int i=0; i<values.lenght; i++){
absolutes[i] = Math.abs(values[i]);
}
return absolutes;
}
int getSumOfAllValues(int[] values){
int total = 0;
for(int i=0; i<values.lenght; i++){
total += values[i];
}
return total;
}
int getSumOfAllAbsolutes(int[] values){
return getSumOfAllValues(makeAllAbsolute(values));
}
Why don't you multiply that number with -1?
Like This:
//Given x as the number, if x is less than 0, return 0 - x, otherwise return x:
return (x <= 0.0F) ? 0.0F - x : x;
If you're interested in the mechanics of two's complement, here's the absolutely inefficient, but illustrative low-level way this is made:
private static int makeAbsolute(int number){
if(number >=0){
return number;
} else{
return (~number)+1;
}
}
Library function Math.abs() can be used.
Math.abs() returns the absolute value of the argument
if the argument is negative, it returns the negation of the argument.
if the argument is positive, it returns the number as it is.
e.g:
int x=-5;
System.out.println(Math.abs(x));
Output: 5
int y=6;
System.out.println(Math.abs(y));
Output: 6
String s = "-1139627840";
BigInteger bg1 = new BigInteger(s);
System.out.println(bg1.abs());
Alternatively:
int i = -123;
System.out.println(Math.abs(i));
To convert negative number to positive number (this is called absolute value), uses Math.abs(). This Math.abs() method is work like this
“number = (number < 0 ? -number : number);".
In below example, Math.abs(-1) will convert the negative number 1 to positive 1.
example
public static void main(String[] args) {
int total = 1 + 1 + 1 + 1 + (-1);
//output 3
System.out.println("Total : " + total);
int total2 = 1 + 1 + 1 + 1 + Math.abs(-1);
//output 5
System.out.println("Total 2 (absolute value) : " + total2);
}
Output
Total : 3
Total 2 (absolute value) : 5
I would recommend the following solutions:
without lib fun:
value = (value*value)/value
(The above does not actually work.)
with lib fun:
value = Math.abs(value);
I needed the absolute value of a long , and looked deeply into Math.abs and found that if my argument is less than LONG.MIN_VAL which is -9223372036854775808l, then the abs function would not return an absolute value but only the minimum value. Inthis case if your code is using this abs value further then there might be an issue.
Can you please try this one?
public static int toPositive(int number) {
return number & 0x7fffffff;
}
if(arr[i]<0)
Math.abs(arr[i]); //1st way (taking absolute value)
arr[i]=-(arr[i]); //2nd way (taking -ve of -ve no. yields a +ve no.)
arr[i]= ~(arr[i]-1); //3rd way (taking negation)
I see people are saying that Math.abs(number) but this method is not full proof.
This fails when you try to wrap Math.abs(Integer.MIN_VALUE) (see ref. https://youtu.be/IWrpDP-ad7g)
If you are not sure whether you are going to receive the Integer.MIN_VALUE in the input. It is always recommended to check for that number and handle it manually.
In kotlin you can use unaryPlus
input = input.unaryPlus()
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/unary-plus.html
Try this in the for loop:
sum += Math.abs(arr[i])
dont do this
number = (number < 0 ? -number : number);
or
if (number < 0) number = -number;
this will be an bug when you run find bug on your code it will report it as RV_NEGATING_RESULT_OF
Related
I have to replicate the luhn algorithm in Java, the problem I face is how to implement this in an efficient and elegant way (not a requirement but that is what I want).
The luhn-algorithm works like this:
You take a number, let's say 56789
loop over the next steps till there are no digits left
You pick the left-most digit and add it to the total sum. sum = 5
You discard this digit and go the next. number = 6789
You double this digit, if it's more than one digit you take apart this number and add them separately to the sum. 2*6 = 12, so sum = 5 + 1 = 6 and then sum = 6 + 2 = 8.
Addition restrictions
For this particular problem I was required to read all digits one at a time and do computations on each of them separately before moving on. I also assume that all numbers are positive.
The problems I face and the questions I have
As said before I try to solve this in an elegant and efficient way. That's why I don't want to invoke the toString() method on the number to access all individual digits which require a lot of converting. I also can't use the modulo kind of way because of the restriction above that states once I read a number I should also do computations on it right away. I could only use modulo if I knew in advance the length of the String, but that feels like I first have to count all digits one-for-once which thus is against the restriction. Now I can only think of one way to do this, but this would also require a lot of computations and only ever cares about the first digit*:
int firstDigit(int x) {
while (x > 9) {
x /= 10;
}
return x;
}
Found here: https://stackoverflow.com/a/2968068/3972558
*However, when I think about it, this is basically a different and weird way to make use of the length property of a number by dividing it as often till there is one digit left.
So basically I am stuck now and I think I must use the length property of a number which it does not really have, so I should find it by hand. Is there a good way to do this? Now I am thinking that I should use modulo in combination with the length of a number.
So that I know if the total number of digits is uneven or even and then I can do computations from right to left. Just for fun I think I could use this for efficiency to get the length of a number: https://stackoverflow.com/a/1308407/3972558
This question appeared in the book Think like a programmer.
You can optimise it by unrolling the loop once (or as many times are you like) This will be close to twice as fast for large numbers, however make small numbers slower. If you have an idea of the typical range of numbers you will have you can determine how much to unroll this loop.
int firstDigit(int x) {
while (x > 99)
x /= 100;
if (x > 9)
x /= 10;
return x;
}
use org.apache.commons.validator.routines.checkdigit.LuhnCheckDigit . isValid()
Maven Dependency:
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
<version>1.4.0</version>
</dependency>
Normally you would process the numbers from right to left using divide by 10 to shift the digits and modulo 10 to extract the last one. You can still use this technique when processing the numbers from left to right. Just use divide by 1000000000 to extract the first number and multiply by 10 to shift it left:
0000056789
0000567890
0005678900
0056789000
0567890000
5678900000
6789000000
7890000000
8900000000
9000000000
Some of those numbers exceed maximum value of int. If you have to support full range of input, you will have to store the number as long:
static int checksum(int x) {
long n = x;
int sum = 0;
while (n != 0) {
long d = 1000000000l;
int digit = (int) (n / d);
n %= d;
n *= 10l;
// add digit to sum
}
return sum;
}
As I understand, you will eventually need to read every digit, so what is wrong with convert initial number to string (and therefore char[]) and then you can easily implement the algorithm iterating that char array.
JDK implementation of Integer.toString is rather optimized so that you would need to implement your own optimalizations, e.g. it uses different lookup tables for optimized conversion, convert two chars at once etc.
final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
99999999, 999999999, Integer.MAX_VALUE };
// Requires positive x
static int stringSize(int x) {
for (int i=0; ; i++)
if (x <= sizeTable[i])
return i+1;
}
This was just an example but feel free to check complete implementation :)
I would first convert the number to a kind of BCD (binary coded decimal). I'm not sure to be able to find a better optimisation than the JDK Integer.toString() conversion method but as you said you did not want to use it :
List<Byte> bcd(int i) {
List<Byte> l = new ArrayList<Byte>(10); // max size for an integer to avoid reallocations
if (i == 0) {
l.add((byte) i);
}
else {
while (i != 0) {
l.add((byte) (i % 10));
i = i / 10;
}
}
return l;
}
It is more or less what you proposed to get first digit, but now you have all you digits in one single pass and can use them for your algorythm.
I proposed to use byte because it is enough, but as java always convert to int to do computations, it might be more efficient to directly use a List<Integer> even if it really wastes memory.
I have searched the internet but have not found any solutions for my question.
I would like to be able to use the same/replicate the type of FLOOR function found in Excel in Java. In particular I would like to be able to provide a value (double or preferably BigDecimal) and round down to the nearest multiple of a significance I provide.
Examples 1:
Value = 24,519.30235
Significance = 0.01
Returned Value = 24,519.30
Example 2:
Value = 76.81485697
Significance = 1
Returned Value = 76
Example 3:
Value = 12,457,854
Significance = 100
Returned Value = 12,457,800
I am pretty new to java and was wondering if someone knew if an API already includes the function or if they would be kind enough to give me a solution to the above. I am aware of BigDecimal but I might have missed the correct function.
Many thanks
Yes you can.
Lets say given numbers are
76.21445
and
0.01
what you can do is multiply 76.21445 by 100 (or divide per 0.01)
round the result to nearest or lower integer (depending which one you want)
and than multiply it by the number again.
Note that it may not exactly print what you want if you will not go for the numbers with decimal precision. (The problem of numbers which in the binary format are not finite in extansion). Also in Math you have the round function taking doing pretty much what you want.
http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html you use it like this
round(200.3456, 2);
one Example Code could be
public static void main(String[] args) {
BigDecimal value = new BigDecimal("2.0");
BigDecimal significance = new BigDecimal("0.5");
for (int i = 1; i <= 10; i++) {
System.out.println(value + " --> " + floor(value, significance));
value = value.add(new BigDecimal("0.1"));
}
}
private static double floor(BigDecimal value, BigDecimal significance) {
double result = 0;
if (value != null) {
result = value.divide(significance).doubleValue();
result = Math.floor(result) * significance.doubleValue();
}
return result;
}
To round a BigDecimal, you can use setScale(). In your case, you want RoundingMode.FLOOR.
Now you need to determine the number of digits from the "significance". Use Math.log10(significance) for that. You'll probably have to round the result up.
If the result is negative, then you have a significance < 1. In this case, use setScale(-result, RoundingMode.FLOOR) to round to N digits.
If it's > 1, then use this code:
value
.divide(significance)
.setScale(0, RoundingMode.FLOOR)
.multiply(significance);
i.e. 1024 and 100 gives 10.24 -> 10 -> 1000.
Is there any way to find the absolute value of a number without using the Math.abs() method in java.
If you look inside Math.abs you can probably find the best answer:
Eg, for floats:
/*
* Returns the absolute value of a {#code float} value.
* If the argument is not negative, the argument is returned.
* If the argument is negative, the negation of the argument is returned.
* Special cases:
* <ul><li>If the argument is positive zero or negative zero, the
* result is positive zero.
* <li>If the argument is infinite, the result is positive infinity.
* <li>If the argument is NaN, the result is NaN.</ul>
* In other words, the result is the same as the value of the expression:
* <p>{#code Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))}
*
* #param a the argument whose absolute value is to be determined
* #return the absolute value of the argument.
*/
public static float abs(float a) {
return (a <= 0.0F) ? 0.0F - a : a;
}
Yes:
abs_number = (number < 0) ? -number : number;
For integers, this works fine (except for Integer.MIN_VALUE, whose absolute value cannot be represented as an int).
For floating-point numbers, things are more subtle. For example, this method -- and all other methods posted thus far -- won't handle the negative zero correctly.
To avoid having to deal with such subtleties yourself, my advice would be to stick to Math.abs().
Like this:
if (number < 0) {
number *= -1;
}
Since Java is a statically typed language, I would expect that a abs-method which takes an int returns an int, if it expects a float returns a float, for a Double, return a Double. Maybe it could return always the boxed or unboxed type for doubles and Doubles and so on.
So you need one method per type, but now you have a new problem: For byte, short, int, long the range for negative values is 1 bigger than for positive values.
So what should be returned for the method
byte abs (byte in) {
// #todo
}
If the user calls abs on -128? You could always return the next bigger type so that the range is guaranteed to fit to all possible input values. This will lead to problems for long, where no normal bigger type exists, and make the user always cast the value down after testing - maybe a hassle.
The second option is to throw an arithmetic exception. This will prevent casting and checking the return type for situations where the input is known to be limited, such that X.MIN_VALUE can't happen. Think of MONTH, represented as int.
byte abs (byte in) throws ArithmeticException {
if (in == Byte.MIN_VALUE) throw new ArithmeticException ("abs called on Byte.MIN_VALUE");
return (in < 0) ? (byte) -in : in;
}
The "let's ignore the rare cases of MIN_VALUE" habit is not an option. First make the code work - then make it fast. If the user needs a faster, but buggy solution, he should write it himself.
The simplest solution that might work means: simple, but not too simple.
Since the code doesn't rely on state, the method can and should be made static. This allows for a quick test:
public static void main (String args []) {
System.out.println (abs(new Byte ( "7")));
System.out.println (abs(new Byte ("-7")));
System.out.println (abs((byte) 7));
System.out.println (abs((byte) -7));
System.out.println (abs(new Byte ( "127")));
try
{
System.out.println (abs(new Byte ("-128")));
}
catch (ArithmeticException ae)
{
System.out.println ("Integer: " + Math.abs (new Integer ("-128")));
}
System.out.println (abs((byte) 127));
System.out.println (abs((byte) -128));
}
I catch the first exception and let it run into the second, just for demonstration.
There is a bad habit in programming, which is that programmers care much more for fast than for correct code. What a pity!
If you're curious why there is one more negative than positive value, I have a diagram for you.
Although this shouldn't be a bottle neck as branching issues on modern processors isn't normally a problem, but in the case of integers you could go for a branch-less solution as outlined here: http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs.
(x + (x >> 31)) ^ (x >> 31);
This does fail in the obvious case of Integer.MIN_VALUE however, so this is a use at your own risk solution.
In case of the absolute value of an integer x without using Math.abs(), conditions or bit-wise operations, below could be a possible solution in Java.
(int)(((long)x*x - 1)%(double)x + 1);
Because Java treats a%b as a - a/b * b, the sign of the result will be same as "a" no matter what sign of "b" is; (x*x-1)%x will equal abs(x)-1; type casting of "long" is to prevent overflow and double allows dividing by zero.
Again, x = Integer.MIN_VALUE will cause overflow due to subtracting 1.
You can use :
abs_num = (num < 0) ? -num : num;
Here is a one-line solution that will return the absolute value of a number:
abs_number = (num < 0) ? -num : num;
-num will equal to num for Integer.MIN_VALUE as
Integer.MIN_VALUE = Integer.MIN_VALUE * -1
Lets say if N is the number for which you want to calculate the absolute value(+ve number( without sign))
if (N < 0)
{
N = (-1) * N;
}
N will now return the Absolute value
Is there a Java function to convert a positive int to a negative one and a negative int to a positive one?
I'm looking for a reverse function to perform this conversion:
-5 -> 5
5 -> -5
What about x *= -1; ? Do you really want a library function for this?
x = -x;
This is probably the most trivial question I have ever seen anywhere.
... and why you would call this trivial function 'reverse()' is another mystery.
Just use the unary minus operator:
int x = 5;
...
x = -x; // Here's the mystery library function - the single character "-"
Java has two minus operators:
the familiar arithmetic version (eg 0 - x), and
the unary minus operation (used here), which negates the (single) operand
This compiles and works as expected.
Another method (2's complement):
public int reverse(int x){
x~=x;
x++;
return x;
}
It does a one's complement first (by complementing all the bits) and then adds 1 to x. This method does the job as well.
Note: This method is written in Java, and will be similar to a lot of other languages
No such function exists or is possible to write.
The problem is the edge case Integer.MIN_VALUE (-2,147,483,648 = 0x80000000) apply each of the three methods above and you get the same value out. This is due to the representation of integers and the maximum possible integer Integer.MAX_VALUE (-2,147,483,647 = 0x7fffffff) which is one less what -Integer.MIN_VALUE should be.
Yes, as was already noted by Jeffrey Bosboom (Sorry Jeffrey, I hadn't noticed your comment when I answered), there is such a function: Math.negateExact.
and
No, you probably shouldn't be using it. Not unless you need a method reference.
original *= -1;
Simple line of code, original is any int you want it to be.
Necromancing here.
Obviously, x *= -1; is far too simple.
Instead, we could use a trivial binary complement:
number = ~(number - 1) ;
Like this:
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
int iPositive = 15;
int iNegative = ( ~(iPositive - 1) ) ; // Use extra brackets when using as C preprocessor directive ! ! !...
System.out.println(iNegative);
iPositive = ~(iNegative - 1) ;
System.out.println(iPositive);
iNegative = 0;
iPositive = ~(iNegative - 1);
System.out.println(iPositive);
}
}
That way we can ensure that mediocre programmers don't understand what's going on ;)
The easiest thing to do is 0- the value
for instance if int i = 5;
0-i would give you -5
and if i was -6;
0- i would give you 6
You can use the minus operator or Math.abs. These work for all negative integers EXCEPT for Integer.MIN_VALUE!
If you do 0 - MIN_VALUE the answer is still MIN_VALUE.
For converting a negative number to positive. Simply use Math.abs() inbuilt function.
int n = -10;
n = Math.abs(n);
All the best!
In kotlin you can use unaryPlus and unaryMinus
input = input.unaryPlus()
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/unary-plus.html
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/unary-minus.html
You can use Math:
int x = Math.abs(-5);
I'm trying to write a method that takes in a base k and a value n to 2 decimal places, then computes the log base k of n without using any of Java's Math.log methods. Here's what I have so far:
public static double log(double k, double n) {
double value = 0.0;
for(double i = 1; i > .001; i /= 10) {
while(!(Math.pow(k, value) >= n )) {
value += i;
}
}
return value;
}
The problem comes up when I try computing log base 4 of 5.0625, which returns 2.0, but should return 1.5.
I have no idea why this isn't working. Any help is appreciated.
No this is not homework, it's part of a problem set that I'm trying to solve for fun.
You're adding the amount i once too ofter. Thus you'll quite soon reach a value larger than the actual value and the while loop will never be entered again.
Subtract i once from the value and you'll be fine:
for(double i = 1; i > .001; i /= 10) {
while(!(Math.pow(k, value) > n )) {
value += i;
}
value -= i;
}
Step through the code on paper:
Iteration: i=1 value = 0.0, calculated power = 1
Iteration: i=1 value = 1.0, calculated power = 4
Iteration: i=1 value = 2.0, calculated power = 16
Now at this point, your value is 2.0. But at no point in the code to you have a way to correct back in the other direction. You need to check for both overshoot and undershoot cases.
This loop
while(!(Math.pow(k, value) >= n )) {
value += i;
}
goes too far. It only stops after the correct value has been surpassed. So when calculating the ones place, 1 isn't enough, so it goes to 2.0, and all subsequent tests show that it is at least enough, so that's where it ends.
Calculating logs by hand, what fun! I suggest doing it out on paper, then stepping through your code with watch variables or outputting each variable at each step. Then check this method out and see if it lines up with what you're doing: Link
You could always look at:
https://stackoverflow.com/a/2073928/251767
It provides an algorithm which will compute a log of any number in any base. It's a response to a question about calculating logs with BigDecimal types, but it could be adapted, pretty easily, to any floating-point type.
Since it uses squaring and dividing by two, instead of using multiple calls to Math.pow(), it should converge pretty quickly and use less CPU resources.