Remove leading zero and delimiter char for BigDecimal - java

Our application can get following numbers:
0.1
0.02
0.003
etc.
These values treated by our code as BigDecimal,as far we operate with money.
There is form on web UI, where user should view these floating parts of prices, transformed to following ones:
1
02
003
The question is,how to trim leading zero and delimiter character in input prices. Perhaps BigDecimal class has standard method something like trimLeadingZeroes(),but can't find any.
UPDATE:
trim just leading zero and delimiter symbol
For instance:
1 is 0.1
27 is 0.27

Something like this?
public String getDecimalFractions(BigDecimal value) {
String strValue = value.toPlainString();
int index = strValue.indexOf(".");
if(index != -1) {
return strValue.substring(index+1, strValue.length());
}
return "0";
}

Have you tried calling BigDecimal.unscaledValue? The downside is that 0.13 would then be 13 whereas you possibly want 1.3... it's slightly hard to tell. If you could give more examples, that would really help.
(That approach would also fail if the value were 1000 to start with - you'd end up with 1...)

Could it be something as simple as doing this:
public static BigDecimal fix(String str){
return new BigDecimal("0." + str);
}
so if you make
public static void main(String[] args) {
System.out.println(fix("1"));
System.out.println(fix("02"));
System.out.println(fix("003"));
}
It will print
0.1
0.02
0.003

when ever you have to deal with splitting something its a good bet Strings can be used for it.
You first just convert the bigdecimal into a string
String s=bd.toPlainString();
Then you simply split it as so
String s2=s.split("\\.")[1];
now String s2 contains the numbers after the delimiter

Conversion from BigDecimal to String:
import java.math.BigDecimal;
public class XXX {
public static void main(String[] args){
doIt("123");
doIt("123.1");
doIt("123.01");
doIt("123.0123");
doIt("123.00123");
}
static void doIt(String input){
BigDecimal bdIn = new BigDecimal(input);
System.out.println(bdIn+" -> "+convert(bdIn));
}
static String convert(BigDecimal bdIn) {
BigDecimal bdOut = bdIn.subtract(bdIn.setScale(0, BigDecimal.ROUND_DOWN));
return bdOut.signum() == 0 ? "0" : bdOut.toPlainString().substring(2);
}
}
Results are:
123 -> 0
123.1 -> 1
123.01 -> 01
123.0123 -> 0123
123.00123 -> 00123
The code works directly with any number and takes into account only the fractional part.
It also handles "0.0" gracefully.
Is this the conversion you wanted?

Here is another simple way of doing this - assuming your input is 1.023456
BigDecimal bd = new BigDecimal("1.023456");
BigInteger bi = bd.toBigInteger();
BigDecimal bd2 = bd.subtract(new BigDecimal(bi));
String afterDecimalPoint = bd2.scale() > 0 ?
bd2.toString().substring(2) : "";
This will give the exact result as you were looking for in bd3, i.e. it'll be 023456 for the above example.
It'll work ok for whole numbers too, due to the condition in last line, i.e. 1 will return ""

You could use the string representation of value (a BigDecimal) and StringUtils.substringAfter to do this:
StringUtils.substringAfter(value.toPlainString(), ".")

How about writing an extension method to extend this type. Simple method might multiply number until > 1
public int trimLeadingZeroes(bigint num) {
while (num < 1)
{
num = num * 10;
}
return num;
}

import java.math.BigDecimal;
import java.math.RoundingMode;
public class RemoveZeroes {
static final int SCALE = 10; // decimal range 0.1 ... 0.0000000001
static final String PADDING = "0000000000"; // SCALE number of zeroes
public static void main(String [] arg) {
BigDecimal [] testArray = {
new BigDecimal(0.27),
new BigDecimal(0.1),
new BigDecimal(0.02),
new BigDecimal(0.003),
new BigDecimal(0.0000000001),
};
for (int i = 0; i < testArray.length; i++) {
// normalize to the same scale
BigDecimal b = testArray[i].setScale(SCALE, RoundingMode.FLOOR);
// pad on the left with SCALE number of zeroes
String step1 = PADDING + b.unscaledValue().toString();
// remove extra zeroes from the left
String step2 = step1.substring(step1.length() - SCALE);
// remove extra zeroes from the right
String step3 = step2.replaceAll("0+$", "");
// print result
System.out.println(step3);
}
}
}

Related

Converting a double to a string fraction(shoe sizes)

So for my project I have to write a method to convert double values to a string. I understand how to do this multiple ways multiple options of formatting. What I'm confused about is how would I turn half sizes(shoes) into a fraction version while still converting it to a string. So
10.5
returns
10 - 1/2
Any tips or helpful pointers are appreciated. Sorry if this is a dumb question I am still learning. :)
What you want can be done with the modulus operator (%) which in Java can be used with floating point values. If you do shoeSize % 1 you will get 0.5 with half sizes and 0.0 with others, so you only have to check that value to add the "1/2" to the string representation or not. Here is a simple example
public class ShoeSize {
double size;
public ShoeSize(double size) { this.size = size; }
public String toString() {
return "" + (int)size + (size % 1 == 0.5? " 1/2" : "");
}
public static void main(String args[]) {
ShoeSize ss1 = new ShoeSize(10.5);
ShoeSize ss2 = new ShoeSize(11);
ShoeSize ss3 = new ShoeSize(11.5);
System.out.println(ss1);
System.out.println(ss2);
System.out.println(ss3);
}
}
The result of the previous code is:
10 1/2
11
11 1/2
However, you really shouldn't go with that approach. That is because depending on the way you manage the shoe size values it can lead to unpredictable results, just because arithmetic in floating point values is not precise as it is with integer values. Some simple operations like the following can introduce enough error so the result is not what you expect:
...
public static void main(String args[]) {
ShoeSize ss = new ShoeSize(10.0);
ss.size += 0.1 + 0.2 + 0.3; // Sum it half
System.out.println(ss);
}
This code now prints 10 instead of 10 1/2.
What should you do instead? Well, there are several ways. You could for example store the shoe size inside ints representing, with each unit representing a half. This internal representation will be much error-prone if you have operations like addSize or subtracts. The only problem will be reading the size of the user; the best way is probably having a list of predefined sizes for the user to choose. Here is an example:
public class ShoeSize {
int halves;
public ShoeSize(double size) { this.halves = (int)(size * 2); }
public String toString() {
return "" + (halves / 2) + (halves % 2 == 1? " 1/2": "");
}
public static void main(String args[]) {
ShoeSize ss = new ShoeSize(10.5);
System.out.println(ss);
}
}
Still better, since the shoe sizes use to be very restricted between certain values, you could represent their values in a single enum. Every enum can be constructed from the human-readable string of the size (ex. "10 1/2") and there would never be problems with invalid shoe sizes. The only problem with this approach is the need to define a custom method to obtain the next and previous shoe sizes, but here is a question that can help you with that:
[What's the best way to implement `next` and `previous` on an enum type?
Try this
public String getShoeSize(double size) {
int s = (int)size;
String shoeSize = Integer.toString(s);
//check if it is a half value
if(size > s) {
shoeSize += " - 1/2";
}
return shoeSize;
}
At first convert value of double to string and split it:
double d=10.5;
String s = String.valueOf(d);
String[] newstr =s.split(".");
then if fraction is limited use switch case for .5 , .25 , .75
but it is not limited ,simplifying fractions is easy if you can folow the steps:
pay attention to this point that maybe your number is not point sign for example 10 that in switch case must be considered
1.find gcd of both num and den, so you have gcd=GCDFind(gcd, num);
2.now, if gcd==1, then the fraction cannot be simplified (it is already in simplified form).
3.if gcd > 1, then newNum = num/gcd; and newDen = den/gcd;
example for limited :
double s = 10.25;
String aString = Double.toString(s);
String[] fraction = aString.split("\\.");
int denominator = (int)Math.pow(10, fraction[1].length());
int numerator = Integer.parseInt(fraction[0] + "" + fraction[1]);
int t=numerator%denominator;
switch(t){
case 0: System.out.println(numerator/denominator);break; //example : 10
case 5: System.out.println(numerator/denominator + " - " +"1/2");break; //example : 10.5
case 25: System.out.println(numerator/denominator + " - " +"1/4");break; //example : 10.25
case 75: System.out.println(numerator/denominator + " - " +"3/4");break; //example : 10.75
default:System.out.println("Not in 1/2, 1/4 or 3/4");
}

Formatting Strings 0.2 to 2000

How would one format the decimal number?
0.2 to show up as 2000.
I also want that even the value 0 would show up as 0000
Your question not really complete, if you want to show integer value of the decimal number (round up/down) then you just need to *10000 then round it, then format it as answered by RC .
public static void main(String[] args) {
float original = 0.2f;
float multiplied = original *10000;
int intvalue = (int)multiplied; // you can change to round up/down
String d = String.format("%04d", intvalue);
System.out.println("Value d : "+d);
}
Check here for the format https://dzone.com/articles/java-string-format-examples
This is the solution assuming that the desired output is 2000:
System.out.println(String.format("%.4f", 0.2).replaceFirst("^0\\.", ""));
Same for 0000:
System.out.println(String.format("%.4f", 0.0).replaceFirst("^0\\.", ""));
You could use a method for that:
private static String convert(double v) {
return String.format("%.4f", v).replaceFirst("^0\\.", "");
}

Format, 2 decimal places for double and 0 for integer in java

I am trying to format a double to exact 2 decimal places if it has fraction, and cut it off otherwise using DecimalFormat
So, I'd like to achieve next results:
100.123 -> 100.12
100.12 -> 100.12
100.1 -> 100.10
100 -> 100
Variant #1
DecimalFormat("#,##0.00")
100.1 -> 100.10
but
100 -> 100.00
Variant #2
DecimalFormat("#,##0.##")
100 -> 100
but
100.1 -> 100.1
Have any ideas what pattern to choose in my case?
The only solution i reached is to use if statement like was mentioned here: https://stackoverflow.com/a/39268176/6619441
public static boolean isInteger(BigDecimal bigDecimal) {
int intVal = bigDecimal.intValue();
return bigDecimal.compareTo(new BigDecimal(intVal)) == 0;
}
public static String myFormat(BigDecimal bigDecimal) {
String formatPattern = isInteger(bigDecimal) ? "#,##0" : "#,##0.00";
return new DecimalFormat(formatPattern).format(bigDecimal);
}
Testing
myFormat(new BigDecimal("100")); // 100
myFormat(new BigDecimal("100.1")); // 100.10
If someone knows more elegant way, please share it!
I believe we need an if statement.
static double intMargin = 1e-14;
public static String myFormat(double d) {
DecimalFormat format;
// is value an integer?
if (Math.abs(d - Math.round(d)) < intMargin) { // close enough
format = new DecimalFormat("#,##0.##");
} else {
format = new DecimalFormat("#,##0.00");
}
return format.format(d);
}
The margin allowed for a number to be regarded as an integer should be chosen according to the situation. Just don’t assume you will always have an exact integer when you expect one, doubles don’t always work that way.
With the above declaration myFormat(4) returns 4, myFormat(4.98) returns 4.98 and myFormat(4.0001) returns 4.00.

how to prefix to a primitive data type

here i have a problem. i want a user to input some numbers, then i will convert the input into a string,i will then count the length of the string, and if it is less than 8,i want to add more zeros to the input to make it 8 so that i can do some staff with the number. i have tried to use decimalformat but its not working. plz help.
thanks in advance
int s=Integer.parseInt(s1.readLine());
String news=String.valueOf(s);
if(news.length()<8){
DecimalFormat myformat=new DecimalFormat("00000000");
String out= myformat.format(s);
int onth=(Integer.valueOf(out)).intValue();
s=onth;
}else{
System.out.format("your number is: %d\n",s);
Forget about using the DecimalFormat.
Change your format to the following
System.out.format("your number is: %08d\n",s)
The %08d will lead with zeros, to a width of 8.
This will only display the number in the format you've requested. As stated elsewhere in this thread, treating it as a number would remove the leading zeros.
If you want to store it in a String variable however, you can use
String intString = String.format("%08d", s);
to store it.
Update *
As you have a specific need to get a series of numbers between a substring
the following code will do what you want.
private static int getSubNumber(int startIndex, int stopIndex, int number) {
String num = String.format("%08d", number);
return Integer.parseInt(num.substring(startIndex, stopIndex));
}
If you pass in the number you want to convert, it will change it to a string, and then convert the substring between the two indexes you pass in back into a number
System.out.println(getSubNumber(2,5,12345678)); // = 345
System.out.println(getSubNumber(2,5,12345)); // = 12
System.out.println(getSubNumber(2,5,123)); // = 0
This is non inclusive, getSubNumber(2,5,...) gets values at position 2,3 and 4 NOT 5.
For your example of 144, use start index 2, stop index 6 for positions 2, 3, 4 and 5
System.out.println(getSubNumber(2,6,144)); // = 1
DecimalFormat is to format numbers in the way we give the pattern.
And to append zeros, please follow this:
Add leading zeroes to a string
If you need to add 0 after the value, you can multiply it by 10 pow the number of missing 0:
int result = Integer.parseInt(news);
if(news.length()<8){
int diff = 8 - news.length();
result = result * Math.pow(10, diff); // ==> result = result * 10^(8 - news.length())
}
I think that's the simpliest way to do that.
Edit Ahhh, yes... There is prefix in the question. Nevermind!
Even if you prefix an int with zeros the actual value will change to the original value. If you want padding you'll have to go with string. The out variable will give you the result.
Update based on comment
import java.util.Scanner;
public class SquareSubString {
public static void main(String[] args) {
String userInputSquare = getSquaredInput();
int digits2to5 = Integer.parseInt(userInputSquare.substring(2, 6));
System.out.println("Squre of digits 2 to 5 is : " + (digits2to5 * digits2to5));
}
private static String getSquaredInput() {
System.out.println("Enter a number : ");
Scanner in = new Scanner(System.in);
int input = in.nextInt();
in.close();
return String.format("%08d", (input * input));
}
}

Java Double get all Digits after dot/comma

it´s a simple task but i´m not able to solve it on my own..
i got
double digit1 = 12.1;
double digit2 = 12.99;
and need a method which gives me this:
anyMethod(digit1); //returns 10
anyMethod(digit2); //returns 99
what i have is
public static void getAfterComma(double digit) {
BigDecimal bd = new BigDecimal(( digit - Math.floor( digit )) * 100 );
bd = bd.setScale(4,RoundingMode.HALF_DOWN);
System.out.println(bd.toBigInteger()); // prints digit1=1 and digit2=99
}
anyway i prefer integer as the returntype..
anybody got a quick solution/tip?
kindly
Why not you simply use:
int anyMethod(double a){
//if the number has two digits after the decimal point.
return (int)((a + 0.001) * 100) % 100;
}
A simple way of getting the fractional part of a double is to use the modulo operator, %. However, you'll have to take into account the fact that floating point arithmetic isn't precise. For example,
System.out.println(12.1 % 1); // outputs 0.09999999999999964
System.out.println(12.99 % 1); // outputs 0.9900000000000002
If you want to get two decimal digits as an int, which is what I think you're asking, you can achieve this, glossing over the floating point issues, like so:
System.out.println(Math.round((12.1 % 1) * 100)); // outputs 10
System.out.println(Math.round((12.99 % 1) * 100)); // outputs 99
However, you should consider going further down the BigDecimal path you started down, which uses arbitrary precision arithmetic. You could do something like this:
System.out.println(new BigDecimal("12.1").remainder(BigDecimal.ONE)); // outputs 0.1
System.out.println(new BigDecimal("12.99").remainder(BigDecimal.ONE)); // outputs 0.99
If, as before, you want two decimal digits from this, you can do this:
System.out.println(new BigDecimal("12.1").remainder(BigDecimal.ONE).multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP).intValue()); // outputs 0.1
System.out.println(new BigDecimal("12.99").remainder(BigDecimal.ONE).multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP).intValue()); // outputs 0.99
Note that there a couple of differences between these last two methods and the first two: they preserve the sign of the argument, so if you use the final example for -12.99, you'll get -99 back, and they treat the fractional part of an integer as 1, so if you use the final example for 12, you'll get 100 back.
It's not necessary to use Number tyeps all the time. You can take advantage of String as a mediator.
String mediator = Double.valueOf(d1).toString();
mediator = mediator.substring(mediator.indexOf('.') + 1);
Integer result = Integer.valueOf(mediator);
Try this out
public static void main(String args[]){
double a=12.99;
double b=12.1;
System.out.println(method(a));
System.out.println(method(b));
}
private static int method(double a) {
return (int) ((a*100)%100);
}
sachin-pasalkar done it! little fix but fine!
public static int anyMethod(double a){
return (int) (a*100)%100;
}
check out this code returns digits after '.' always. Without any extra parameters other than double variable.
public int anyMethod(double d)
{
String numString = d+"";
return Integer.parseInt(numString.substring(numString.indexOf('.')+1));
}
If I understand correctly, you need to return n digits after the dot for a given double number. So... let's see:
public int decimalDigits(double x, int n) {
double ans;
ans = (x - (int) x) * Math.pow(10, n);
return (int) ans;
}
Done. Hope this helps you.
For your specific example, 'n = 2' should do.

Categories

Resources