I need to put the decimal separator point in a Long, I have tried in several ways, but I need it to be dynamic since the decimal separator can change, I have tried with DecimalFormat format = new DecimalFormat("###.##"); but this is not dynamic and it doesn't work the way I wanted it to
Example 1
long amount = 123456;
int decimal = 2;
The result should be Double newAmount = 1234.56
Example 2
long amount = 123456;
int decimal = 4;
The result should be Double newAmount = 12.3456
If I understand correctly, this is what you are trying to achieve:
Long amount = 123456;
int decimal = 2;
double newAmount = amount.doubleValue();
newAmount = newAmount / Math.pow(10, decimal);
Use the pow method of java.lang.math to calculate the power of a number.
Be careful to declare your variable as an object of type Long and not a primitive type if you want to use one of its functions.
As suggested, it is even simpler to just use a double variable instead of a long from the start:
double amount = 123456;
int decimal = 2;
amount = amount / Math.pow(10, decimal);
You can get the required number by dividing the given number by 10 ^ decimalPlaces e.g.
public class Main {
public static void main(String[] args) {
// Test
System.out.println(getNum(123456, 2));
System.out.println(getNum(123456, 4));
}
static double getNum(long val, int decimalPlaces) {
return val / Math.pow(10, decimalPlaces);
}
}
Output:
1234.56
12.3456
All the other answers suggest converting to double and then scaling by powers of 10 before displaying. This will result in some unexpected results because of a loss of precision in the scaling operation. For the complete, gory details on why, please read
What Every Computer Scientist Should Know About Floating-Point Arithmetic and
Is Floating Point Broken?
As to your problem, you should be doing the work using BigDecimal. Converting from long (or Long) to BigDecimal does not lose precision, and will always produce the expected results.
BigDecimal even has a method to do the scaling for you:
long amount = 123456;
int decimal = 2;
BigDecimal n = BigDecimal.valueOf(amount).scaleByPowerOfTen(-decimal);
Output:
1234.56
I have a float value of a current weight like e.g. "79.3" kilograms.
I split the float value into a kilogram and a grams value.
I get the right amount of kilograms when parsing the float-value to int.
Then I get the fractional part of the float-value. This fractional part looks like "0,3" which means 0.3 kilograms or 300grams.
In my Programm I can only have 0,100,200,..,900 Grams which would stand for 0-9.
My goal is to remove the "0," so I only get the value of "3".
This is my code for now and I tried some decimal formatting too, but I didn't know how to do it:
public void setCurrentWeightInTheNumberPickers() {
float currentWeightAsFloat = weight_dbHandler.getCurrentWeightFloat();
int currentWeightKilograms = (int) currentWeightAsFloat;
double fractionOfGrams = currentWeightAsFloat % 1;
DecimalFormat df1 = new DecimalFormat("0.##");
String rounded = df1.format(fractionOfGrams);
rounded.replaceFirst("^0+(?!$)", "");
} //public void setCurrentWeightInTheNumberPickers()
Given a string
String gram = "0,3";
you can just do:
gram = gram.substring(gram.lastIndexOf(",") + 1);
which gives the following output when printed
3
Or you can simply do that. No need for strings.
float f = 3.3f;
int g = (int)f;
int h = Math.round((f - g)*10);
and since h is supposed to be grams, you might as well make it *1000
I view this primarily as a math, not a Java, problem. Given a float input in units of kilograms, to obtain only the kilogram component, we can take the floor. To get the grams component, we can multiply by 1000 and then take the mod of 1000.
double input = 79.321;
double kg = Math.floor(input);
System.out.println("kilograms: " + kg);
double g = Math.floor((1000*input) % 1000);
System.out.println("grams: " + g);
kilograms: 79.0
grams: 321.0
Note: I am using double here instead of float, only because Math.floor returns double as its return value.
I want to get the first 2 decimal digits (without rounding ).
Here is an example:
49455.10937 --> 49455.10
formatting to String is an expensive operation (in performance terms)
this can be done with math operations:
double x = 49455.10937;
x *= 100; // moves two digits from right to left of dec point
x = Math.floor(x); // removes all reminaing dec digits
x /= 100; // moves two digits from left to right of dec point
double decimalValue = 49455.10937;
String decimalValueStr = String.valueOf(decimalValue);
int indexDot = decimalValueStr.lastIndexOf('.');
int desiredDigits=3;
String decimal = decimalValueStr.substring(0, (indexDot + 1) + desiredDigits);
decimalValue = Double.parseDouble(decimal);
System.out.println(decimalValue);
//49455.109 is console output (change desired digits)
You can use a formatter to format the double value as follows
StringBuilder sb = new StringBuilder();
Formatter formatter = new Formatter(sb, Locale.US);
Double value = 49455.10937;
System.out.println(formatter.format("The value: %.2f", value));
I am trying to make my number move the first character to the end.
For example I would have my double d.
double d = 12345.6;
double result = 2345.61;
Currently I am removing the first character of d with:
d = d % (int) Math.pow(10, (int) Math.log10(d));
But I do not know how to store the character I am removing so I could put it at the end. I know I could just convert d into an array or a string, but I want to keep it as a double if at all possible.
I am getting my double from a nanosecond clock using Instant.now, so I can guarantee it starts as an 8 digit positive int, which I start by adding .0 to so I can make it a double. I know I can just use string (as I mentioned in the post), but I was wondering if there was a way to do it without conversions.
Thanks for helping!
(this is my first post I apologize if it is bad)
This is a pretty tough problem, and this isn't a working answer but it is pretty close. The only trouble I ran into was java adding decimals to the end of my doubles because it can't represent a number very well. My solution might get you on the right path. The appendChar was messing up because it was adding digits to the end of the double, other than that problem this would have worked.
public static void main(String[] args) {
double test = 4234.1211;
boolean hasDecimals = test % 1 > 0;
double[] leadChar = getLeadDigitAndMulti(test);
double appendedValue = appendLeadChar(test, (int) leadChar[1], hasDecimals);
}
public static double[] getLeadDigitAndMulti(double value) {
double[] result = new double[2];
int multiplier = 10;
int currentMultiplier = 1;
while (value > currentMultiplier) {
currentMultiplier *= multiplier;
}
currentMultiplier /= multiplier;
double trail = value % (currentMultiplier);
result[0] = currentMultiplier;
double lead = value - trail;
lead /= currentMultiplier;
result[1] = lead;
return result;
}
public static double appendLeadChar(double value, int leadChar, boolean hasDecimals) {
if (!hasDecimals) {
return (value * 10) + leadChar;
}
int multiplier = 10;
double currentMultiplier = 1;
while (value > 0) {
value %= currentMultiplier;
currentMultiplier = currentMultiplier / multiplier;
}
return 0;
}
I would start with at least figuring out how many digits long your double is. I'm not too sure of how to make it work but I saw another question that would answer it. Here is the link to that thread:
Number of decimal digits in a double
And the closest code on there that I could find to find the length would be:
double d= 234.12413;
String text = Double.toString(Math.abs(d));
int integerPlaces = text.indexOf('.');
int decimalPlaces = text.length() - integerPlaces - 1;
NOTE THIS SEGMENT OF CODE IS NOT MINE, credit goes to Peter Lawrey who originally answered this in the linked thread.
Then using code or modified code similar to above ^ assuming you would find how to find the length of the double or the total number of digits of your double, you would create a new int or double variable that would store the double and round it using BigDecimal to the highest place value. The place that the BigDecimal will round to will be set using a 10*pow(x) where x is the number of places AFTER the decimal.
Sorry I am unable to provide code on how to make this actually run because I am pretty new to java. Here is what I mean in more detailed pseudocode:
double d = 12345.6; //the double you are evaluating
double dNoDecimal; //will be rounded to have no decimal places in order to calculate place of the 1st digit
double dRoundedFirstDigit; //stores the rounded number with only the 1st digit
double firstDigit; //stores first digit
dNoDecimal = d; //transfers value
dNoDecimal = [use BigDecimal to round so no decimal places will be left]
//dNoDecimal would be equal to 12345 right now
[use above code to find total amount of place values]
[knowing place values use BigDecimal to round and isolate 1st digit of double]
dRoundedFirstDigit = dNoDecimal; //transfers value
dRoundedFirstDigit = [round using BigDecimal to leave only 1st digit]
firstDigit = [dRoundedFirstDigit cut down to 1st digit value using length found from before, again an equation will be needed]
//Now use reverse process
//do the same thing as above, but find the number of decimals by rounding down to leave only decimals (leaving only .6)
//find the length
//use length to calculate what to add to the original value to move the digit to the end (in this case would be d += firstDigit*Math.pow(10,-2))
I apologize if I just made everything seem more confusing, but I tried my best, hope this helps.
Also, doing this without an array or string is really difficult... may I ask why you need to do it without one?
For example I have the variable 3.545555555, which I would want to truncate to just 3.54.
If you want that for display purposes, use java.text.DecimalFormat:
new DecimalFormat("#.##").format(dblVar);
If you need it for calculations, use java.lang.Math:
Math.floor(value * 100) / 100;
DecimalFormat df = new DecimalFormat(fmt);
df.setRoundingMode(RoundingMode.DOWN);
s = df.format(d);
Check available RoundingMode and DecimalFormat.
None of the other answers worked for both positive and negative values ( I mean for the calculation and just to do "truncate" without Rounding). and without converting to string.
From the How to round a number to n decimal places in Java link
private static BigDecimal truncateDecimal(double x,int numberofDecimals)
{
if ( x > 0) {
return new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_FLOOR);
} else {
return new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_CEILING);
}
}
This method worked fine for me .
System.out.println(truncateDecimal(0, 2));
System.out.println(truncateDecimal(9.62, 2));
System.out.println(truncateDecimal(9.621, 2));
System.out.println(truncateDecimal(9.629, 2));
System.out.println(truncateDecimal(9.625, 2));
System.out.println(truncateDecimal(9.999, 2));
System.out.println(truncateDecimal(-9.999, 2));
System.out.println(truncateDecimal(-9.0, 2));
Results :
0.00
9.62
9.62
9.62
9.62
9.99
-9.99
-9.00
Note first that a double is a binary fraction and does not really have decimal places.
If you need decimal places, use a BigDecimal, which has a setScale() method for truncation, or use DecimalFormat to get a String.
Formating as a string and converting back to double i think will give you the result you want.
The double value will not be round(), floor() or ceil().
A quick fix for it could be:
String sValue = (String) String.format("%.2f", oldValue);
Double newValue = Double.parseDouble(sValue);
You can use the sValue for display purposes or the newValue for calculation.
If, for whatever reason, you don't want to use a BigDecimal you can cast your double to an int to truncate it.
If you want to truncate to the Ones place:
simply cast to int
To the Tenths place:
multiply by ten
cast to int
cast back to double
and divide by ten.
Hundreths place
multiply and divide by 100 etc.
Example:
static double truncateTo( double unroundedNumber, int decimalPlaces ){
int truncatedNumberInt = (int)( unroundedNumber * Math.pow( 10, decimalPlaces ) );
double truncatedNumber = (double)( truncatedNumberInt / Math.pow( 10, decimalPlaces ) );
return truncatedNumber;
}
In this example, decimalPlaces would be the number of places PAST the ones place you wish to go, so 1 would round to the tenths place, 2 to the hundredths, and so on (0 rounds to the ones place, and negative one to the tens, etc.)
You can use NumberFormat Class object to accomplish the task.
// Creating number format object to set 2 places after decimal point
NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(2);
nf.setGroupingUsed(false);
System.out.println(nf.format(precision));// Assuming precision is a double type variable
3.545555555 to get 3.54.
Try Following for this:
DecimalFormat df = new DecimalFormat("#.##");
df.setRoundingMode(RoundingMode.FLOOR);
double result = new Double(df.format(3.545555555);
This will give= 3.54!
Maybe Math.floor(value * 100) / 100? Beware that the values like 3.54 may be not exactly represented with a double.
Here is the method I use:
double a=3.545555555; // just assigning your decimal to a variable
a=a*100; // this sets a to 354.555555
a=Math.floor(a); // this sets a to 354
a=a/100; // this sets a to 3.54 and thus removing all your 5's
This can also be done:
a=Math.floor(a*100) / 100;
I used Math.floor() method and basic moving of decimal places by (100 = 2).
//3.545555555 to 3.54 by floor method
double x = 3.545555555;
double y = Math.floor(x * 100); //354
double z = y / 100; //3.54
Maybe following :
double roundTwoDecimals(double d) {
DecimalFormat twoDForm = new DecimalFormat("#.##");
return Double.valueOf(twoDForm.format(d));
}
I have a slightly modified version of Mani's.
private static BigDecimal truncateDecimal(final double x, final int numberofDecimals) {
return new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_DOWN);
}
public static void main(String[] args) {
System.out.println(truncateDecimal(0, 2));
System.out.println(truncateDecimal(9.62, 2));
System.out.println(truncateDecimal(9.621, 2));
System.out.println(truncateDecimal(9.629, 2));
System.out.println(truncateDecimal(9.625, 2));
System.out.println(truncateDecimal(9.999, 2));
System.out.println(truncateDecimal(3.545555555, 2));
System.out.println(truncateDecimal(9.0, 2));
System.out.println(truncateDecimal(-9.62, 2));
System.out.println(truncateDecimal(-9.621, 2));
System.out.println(truncateDecimal(-9.629, 2));
System.out.println(truncateDecimal(-9.625, 2));
System.out.println(truncateDecimal(-9.999, 2));
System.out.println(truncateDecimal(-9.0, 2));
System.out.println(truncateDecimal(-3.545555555, 2));
}
Output:
0.00
9.62
9.62
9.62
9.62
9.99
9.00
3.54
-9.62
-9.62
-9.62
-9.62
-9.99
-9.00
-3.54
A quick check is to use the Math.floor method. I created a method to check a double for two or less decimal places below:
public boolean checkTwoDecimalPlaces(double valueToCheck) {
// Get two decimal value of input valueToCheck
double twoDecimalValue = Math.floor(valueToCheck * 100) / 100;
// Return true if the twoDecimalValue is the same as valueToCheck else return false
return twoDecimalValue == valueToCheck;
}
double value = 3.4555;
String value1 = String.format("% .3f", value) ;
String value2 = value1.substring(0, value1.length() - 1);
System.out.println(value2);
double doublevalue= Double.valueOf(value2);
System.out.println(doublevalue);
double firstValue = -3.1756d;
double value1 = (((int)(Math.pow(10,3)*firstValue))/Math.pow(10,3));
In this solution, this will TRUNCATE a double to only two decimal places. This solution will not ROUND OFF the double value.
double myDoubleNumber = 3.545555555;
DecimalFormat df = new DecimalFormat("#.##");
df.setRoundingMode(RoundingMode.DOWN);
double myDoubleNumberTruncated = Double.parseDouble(df.format(myDoubleNumber));
System.out.println(myDoubleNumberTruncated);
This will output 3.54
DecimalFormat("#.##") - Here, I entered two hash symbols(##) after the decimal point. Hence, this will truncate the number up to two decimal places.
This will work for both Positive & Negative values.
This worked for me:
double input = 104.8695412 //For example
long roundedInt = Math.round(input * 100);
double result = (double) roundedInt/100;
//result == 104.87
I personally like this version because it actually performs the rounding numerically, rather than by converting it to a String (or similar) and then formatting it.