Java Round decimal - specific case second decimal Zero - java

Given this numbers:
150.00
150.26
I need to round like this:
If the second value of decimal part is zero (0), then the new value should be 150.0
If the second value of decimal part is different than zero (0), then the new value keeps both decimals Ex.: 150.26
Is there a rounding method that can do this?
Thanks.
My code here:
String monto = "150.10";//150.26
String nuevoMonto = "";
String[] valores = monto.split("\\.");
System.out.println("Valores : " + valores);
System.out.println("Valores length: " + valores.length);
for (int i = 0; i < valores.length; i++) {
System.out.println("-->Valor: " + valores[i]);
}
if (valores.length == 2) {
nuevoMonto = valores[1];
System.out.println("Nuevomonto: " + nuevoMonto);
if (nuevoMonto.length() == 2) {
System.out.println("Dos posiciones decimales");
System.out.println(nuevoMonto.indexOf("0"));
if (nuevoMonto.indexOf("0") == 1) {
nuevoMonto = valores[0] + "." + nuevoMonto.substring(0, 1);
}
}
}
System.out.println("Nuevo monto: " + nuevoMonto);

try something like this:
DecimalFormat decimalFormat = new DecimalFormat("#.0#");
System.out.println(decimalFormat.format(150.09));
System.out.println(decimalFormat.format(150.10));
The string inside the new decimal format allows #s to be trimmed, and 0s are forced to stay

If you have a string to start with, perhaps there is no point parsing it to a floating point number and then reformatting it. Another approach is to use a regexp for this:
String monto = "150.10";
String nuevoMonto = monto.replaceAll("(?<=\\.\\d)0$", "")
The regexp consist of two parts. The first part (?<=\\.\\d) says the match need to be preceded by a dot and a digit. The second part 0$ matches the trailing zero at the end of the string. We replace it with nothing.

There is an expression in Java called floor method which can be used to always bring a value with any form of rounding to an integer value with any relevant decimal points removed from the data
a simple check for this wold be to take the data and check if the data is not modulo or mod of a zero
sample code might look like this.
if ((monto % 0.1 ) == 0)
{
//has no relevant data so it should be floored
Nuevomonto = floor (monto);
}
else
{
Nuevomonto = monto;
}
hope that helps.

Related

How to add numbers onto the back of an existing number (GUI Calculator)

So for school I need to make a GUI calculator, I have fully made the calculator working, but only up to single digit arthmatic (1+1) but now I wish to make it that that I can have multiple digits inputed (123 + 45) this is my code:
b1.addActionListener(e -> {System.out.println("Response:1 was inputed onto calculator");
if(arth == "") {
num1S = Double.toString(num1);
Tnum1S = "1" + num1S;
num1 = Double.parseDouble(Tnum1S);
l.setText(Tnum1S);
Tnum1S = "";
} else {
num2S = Double.toString(num2);
Tnum2S = num2S + "1";
num2 = Double.parseDouble(Tnum2S);
l.setText(Tnum2S);
Tnum2S = "";
}});
//T at the start means Temporary, S at te end means a String, normally my numbers are set to double.
This is a screenshot of my results from my try of making this work does anyone know how to make it that the number is not added into the decimal places?
Maybe this is what you want:
DecimalFormat format = new DecimalFormat("#.#"); // you can change it here
System.out.println(format.format(d));
If you take a look at the line Tnum1S = "1" + num1S; , you are essentially concatenating 1 to the content of num1S as a String. Instead, for building a calculator you should be adding them as doubles and then push to the user interface.
num1S contains the String equivalent of num1.
num1S = Double.toString(num1);
Tnum1S now gets a 1 concatenated with num1S.
Tnum1S = "1" + num1S;
You are now converting the concatenated value ( not added value )back to Double
num1 = Double.parseDouble(Tnum1S);
You are finally setting it on the UI.
l.setText(Tnum1S);
Instead you should,
Convert the numbers of your interest from String to Double.
Perform the operation as a Double.
Push the result back to the user interface as a String.
In short, in your case, you are using the concatenation operation on String rather than the addition operation on a double.

Java automatic filling of ArrayList, searching for better options

I'm using this code here to automatically fill a string array list with the directory path of obj files for later use in animations, but there's a small problem with this:
private List<String> bunny_WalkCycle = new ArrayList<String>();
private int bunny_getWalkFrame = 0;
private void prepare_Bunny_WalkCycle() {
String bunny_walkFrame = "/bunnyAnimation/bunnyFrame0.obj";
while(bunny_WalkCycle.size() != 30) { // 30 obj files to loop through
if(bunny_getWalkFrame != 0) {
bunny_walkFrame =
"/bunnyAnimation/bunnyWalkAnim/bunnyWalkFrame_"+bunny_getWalkFrame+".obj";
}
bunny_WalkCycle.add(bunny_getWalkFrame);
bunny_getWalkFrame++;
}
}
Now the problem is that the naming convention in blender for animations has zeros before the actual numbers, so something like this:
bunnyWalkFrame_000001.obj
bunnyWalkFrame_000002.obj
bunnyWalkFrame_000003.obj
...
bunnyWalkFrame_000030.obj
With my prepare_Bunny_WalkCycle method I cannot account for the zeros so I would change the names and get rid of the zeros.. This may be okay for not so many frames but once I hit 100 frames it would get painfull.. So there's my question:
What would be an intelligent way to account for the zeros in the code instead of having to rename every file manually and remove them?
I think you can solve your problem with "String.format":
String blenderNumber = String.format("%06d", bunny_getWalkFrame);
Explanation:
0 -> to put leading zeros
6 -> "width" of them / amount of them
And so this would be your new bunny_walkFrame:
bunny_walkFrame = "/bunnyAnimation/bunnyWalkAnim/bunnyWalkFrame_" + blenderNumber + ".obj";
You can use String.format() to pad your numbers with zeros:
String.format("%05d", yournumber);
Here are two options. First, you can use a string formatter to create your filenames with leading zeros:
bunny_WalkCycle.add("/bunnyAnimation/bunnyFrame0.obj");
for (int frame = 1; frame <= 30; frame++) {
bunny_WalkCycle.add(
String.format("/bunnyAnimation/bunnyWalkAnim/bunnyWalkFrame_%06s.obj", frame));
}
The second option is, if you already have all the required files in the directory, you can get them all in one go:
bunny_WalkCycle.add("/bunnyAnimation/bunnyFrame0.obj");
bunny_WalkCycle.addAll(Arrays.asList(new File("/bunnyAnimation/bunnyWalkAnim").list()));
There are two ways you could do that:
Appending the right number of leading zeroes, or using a String formatter.
bunny_walkFrame = "/bunnyAnimation/bunnyWalkAnim/bunnyWalkFrame_" + String.format("%05d", bunny_getWalkFrame) + ".obj";
OR
bunny_walkFrame = "/bunnyAnimation/bunnyWalkAnim/bunnyWalkFrame_" + getLeadingZeroes(bunny_getWalkFrame) + String.valueOf(bunny_getWalkFrame) + ".obj";
where
private String getLeadingZeroes(int walk) {
String zeroes = "";
int countDigits = 0;
while (walk > 0) {
countDigits++;
walk /= 10;
}
for (int i = 1; i <= (nZeroes - countDigits); i++) {
zeroes += "0";
}
return zeroes;
}
Here ya go:
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html
Just specify how many digits you want. Set it to one. If it has to it will push over (so it won't cut digits off)

Remove trailing zero in Java

I have Strings (from DB), which may contain numeric values. If it contains numeric values, I'd like to remove trailing zeros such as:
10.0000
10.234000
str.replaceAll("\\.0*$", ""), works on the first one, but not the second one.
A lot of the answers point to use BigDecimal, but the String I get may not be numeric. So I think a better solution probably is through the Regex.
there are possibilities:
1000 -> 1000
10.000 -> 10 (without point in result)
10.0100 -> 10.01
10.1234 -> 10.1234
I am lazy and stupid, just
s = s.indexOf(".") < 0 ? s : s.replaceAll("0*$", "").replaceAll("\\.$", "");
Same solution using contains instead of indexOf as mentioned in some of the comments for easy understanding
s = s.contains(".") ? s.replaceAll("0*$","").replaceAll("\\.$","") : s
Use DecimalFormat, its cleanest way
String s = "10.1200";
DecimalFormat decimalFormat = new DecimalFormat("0.#####");
String result = decimalFormat.format(Double.valueOf(s));
System.out.println(result);
Kent's string manipulation answer magically works and also caters for precision loss, But here's a cleaner solution using BigDecimal
String value = "10.234000";
BigDecimal stripedVal = new BigDecimal(value).stripTrailingZeros();
You can then convert to other types
String stringValue = stripedVal.toPlainString();
double doubleValue = stripedVal.doubleValue();
long longValue = stripedVal.longValue();
If precision loss is an ultimate concern for you, then obtain the exact primitive value. This would throw ArithmeticException if there'll be any precision loss for the primitive. See below
int intValue = stripedVal.intValueExact();
String value = "10.010"
String s = new DecimalFormat("0.####").format(Double.parseDouble(value));
System.out.println(s);
Output:
10.01
I find all the other solution too complicated. Simply
s.replaceFirst("\\.0*$|(\\.\\d*?)0+$", "$1");
does the job. It tries the first alternative first, so that dot followed by all zeros gets replaced by nothing (as the group doesn't get set). Otherwise, if it finds a dot followed by some digits (as few as possible due to the lazy quantifier *?) followed by some zeros, the zeros get discarded as they're not included in the group. It works.
Warning
My code relies on my assumption that appending a unmatched group does nothing. This is true for the Oracle implementation, but not for others, including Android, which seem to append the string "null". I'd call the such implementations broken as it just may no sense, but they're correct according to the Javadoc.
The following works for all the following examples:
"1" -> "1"
"1.0" -> "1"
"1.01500" -> "1.015"
"1.103" -> "1.103"
s = s.replaceAll("()\\.0+$|(\\..+?)0+$", "$2");
What about replacing
(\d*\.\d*)0*$
by
\1
?
You could replace with:
String result = (str.indexOf(".")>=0?str.replaceAll("\\.?0+$",""):str);
To keep the Regex as simple as possible. (And account for inputs like 1000 as pointed out in comments)
My implementation with possibility to select numbers of digits after divider:
public static String removeTrailingZero(String number, int minPrecise, char divider) {
int dividerIndex = number.indexOf(divider);
if (dividerIndex == -1) {
return number;
}
int removeCount = 0;
for (int i = dividerIndex + 1; i < number.length(); i++) {
if (number.charAt(i) == '0') {
removeCount++;
} else {
removeCount = 0;
}
}
int fracLen = number.length() - dividerIndex - 1;
if (fracLen - removeCount < minPrecise) {
removeCount = fracLen - minPrecise;
}
if (removeCount < 0) {
return number;
}
String result = number.substring(0, number.length() - removeCount);
if (result.endsWith(String.valueOf(divider))) {
return result.substring(0, result.length() - 1);
}
return result;
}
In addition to Kent's answer.
Be careful with regex in Kotlin. You have to manually write Regex() constructor instead of a simple string!
s = if (s.contains("."))
s.replace(Regex("0*\$"),"").replace(Regex("\\.\$"),"")
else s
Try to use this code:
DecimalFormat df = new DecimalFormat("#0.#####");
String value1 = df.format(101.00000);
String value2 = df.format(102.02000);
String value3 = df.format(103.20000);
String value4 = df.format(104.30020);
Output:
101
102.02
103.2
104.3002
Separate out the fraction part first. Then you can use the below logic.
BigDecimal value = BigDecimal.valueOf(345000);
BigDecimal div = new BigDecimal(10).pow(Integer.numberOfTrailingZeros(value.intValue()));
System.out.println(value.divide(div).intValue());

Regex expression w/ set length

I have several thousands of rows that I'm loading into a database utilizing Pentaho. I must keep the string value length at 4 characters. The source file may only have a single character but it is still needed to keep the length at 4 characters to maintain consistency in the database.
Example:
Source: 10
Database expected results: 0010
I'm using a replace in string transformation or could use a java expression, which ever one works. Please help and provide a resolution utilizing either method (Regex or Javascript expression).
Thanks,
In Java you can use String.format(...) with a format specifier to pad your number with zeroes to 4 digits:
String.format("%04d", yournumber);
In Javascript you can use sprintf(...) for the same task:
var s = sprintf("%04d", yournumber);
So apparently sprintf() isn't standard Javascript but is a library you can download if you like. You can always to do this to get your 4 digits though:
// take the last 4 digits from the right
var s = String("0000" + yournumber).slice(-4);
And you could actually turn this into a simple left-padding function:
String.prototype.leftPad = function(paddingValue, paddingLength) {
return (new Array(paddingLength + 1).join(paddingValue) + this).slice(-paddingLength);
};
var s = String(yournumber).leftPad("0", 4)
(If you mean Javascript):
var str = "10";
function padIt(s) {
s = ""+s;
while (s.length < 4) {
s = "0" + s;
}
return s;
}
console.log(padIt(str));
http://jsfiddle.net/EzqRM/1/
For arbitrary padding of numbers, in javascript:
// padLeft(
// number to pad
// length to pad to
// character to pad with[optional, uses 0's if not specified]
// )
function padLeft(num, pad, padchr) {
num = "" + num;
pad = (pad || num.length) + 1;
return (num.length < pad ? new Array(pad - num.length).join(padchr || "0") : "") + num;
}
// returns "0010"
var input = 10
padded = padLeft(input, 4)

Parse a number with Java

I have a string which I assume is a zero padded representation of an integer, of 6 digits, e.g.:
"001234"
I want to parse it to a Long object, but I want to check that it's exactly the same format; I would like to return errors if it's not of length 6, not zero padded, etc.
In C I would use some variant of scanf. What's the Java way?
if(s.length() != 6)
throw new IllegalArgumentException("Input is not of length 6: " + s);
Pattern allDigits = Pattern.compile( "[0-9]+" );
if(!allDigits.matcher(s).matches())
throw new IllegalArgumentException("Input is not numeric: " + s);
long val = Long.parseLong(s);
This code snippet might help you.
String test = "001234";
long correctValue = 0;
if (test.charAt(0) == '0' || test.length() != 6) {
System.out.println("padded or incorrect length");
} else {
correctValue = Long.parseLong(test);
}
System.out.println(correctValue);
Try this, the trick is that Long.parseLong does not accept no trailing or leading spaces, but accepts leading zeroes, so you need only to check that the length = 6
String input = "001234";
if (input.length() != 6) {
throw new IllegalArgumentException(input);
}
long l = Long.parseLong(input);
Actually it accepts a non zero padded "123456" but I think it corresponds to your requirements.
A variant of Aleksander Blomskøld's answer:
Pattern allDigits = Pattern.compile("^\d{6}$");
if (!allDigits.matcher(s).matches())
throw new IllegalArgumentException("Input is not numeric: " + s);
long val = Long.parseLong(s);
I would do the String validation in regexp.
if is valid, than I would use Long.parseLong
Long#parseLong would get you most of the way. Just check that is has six digits, and that the result is positive. It cannot be padded with anything else but 0 (because then the parse will fail).
Do you mean you want to check the length like
if (text.length() != 6)

Categories