I don't know how to explain this well, but for example I have a number:
0.00000548347554 and want to make 0.000005483 from it, or
0.0683453248 to 0.06843, etc.
This assumes your number is a string:
String tmp = "0.0683453248";
String[] tmpA = tmp.split("");
ArrayList<String> res = new ArrayList<>();
for(int i = 0; i < tmpA.length; i++){
res.add(tmpA[i]);
if(!tmpA[i].equals(".") && Integer.parseInt(tmpA[i]) > 0){
res.add(tmpA[i + 1]);
res.add(tmpA[i + 2]);
res.add(tmpA[i + 3]);
break;
}
}
String result = String.join("",res);
Using the solution from this answer, you can convert the given number into a string and then use the regex replacement to get the required string out of it.
Demo:
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Test
System.out.println(doubleToString(0.00000548347554));
System.out.println(doubleToString(0.0683453248));
}
static String doubleToString(double n) {
DecimalFormat df = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
df.setMaximumFractionDigits(340);
return df.format(n).replaceAll("(\\d*\\.0*[1-9]{4})\\d*", "$1");
}
}
Output:
0.000005483
0.06834
ONLINE DEMO
Explanation of the regex:
(: Start of capturing group#1
\\d*\\.: Digit(s) followed by .
0*: Any number of zeros
[1-9]{4}: Non-zero four digits
): End of capturing group#1
\d* : Any digit any number of times
For small numbers BigDecimal can be used:
BigDecimal significant(double number, int count) {
if (count < 1)
throw new IllegalArgumentException("invalid count: " + count);
BigDecimal big = BigDecimal.valueOf(number);
if (big.precision() <= count) {
return big;
} else {
return big.setScale(big.scale()-big.precision()+count, RoundingMode.HALF_EVEN);
}
}
precision() returns the number of significant digits;
the method changes the scale so only the desired number of digits is present.
The if is used to avoid more zeros than the input if this has less than count digits.
Use doubleValue() to convert the result to double if needed (may suffer from rounding error).
To get a string, use toPlainString(), which will transform the result to string without using the exponential notation.
Rounding mode can also be changed if desired.
Note: it can also be used with larger numbers, it basically will replace digits by zero like in significant(12345,2) -> 12000 (or 1.2E+4)
Related
I'm trying to learn java, and I can't seem to understand recursion. I can understand how recursion can be used to add and do other basic math operations but how can recursion be used to reverse manipulate integers and individual integer digits.
example:
a method takes a single positive integer argument and displays its base five equivalent. 231 returns 1411 but the code below returns 1141. how would I reverse the order of integers put out?
public void base5(int n){
int rem=n%5;
int vis=n/5;
if(n!=0){
// System.out.print(rem/*+"|"*/);
//
// rem=(rem+rem)*10;
// System.out.print("\n||"+n+"||\n");
System.out.print(rem);
base5(vis);
}
else{
return;
}
}
The algorithm for getting individual digits of an integer, from right to left, is well known. See How to get the separate digits of an int number?.
I won't "explain" recursion, but I'll give you one possible solution for first problem:
a method takes a single positive integer and displays it with commas
inserted every three digits
import java.util.Scanner;
class Main {
public static void main( String [] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter your positive integer: ");
long number = sc.nextLong();
String result = addCommas(number);
System.out.println(result);
}
public static String addCommas(long num) {
return addCommas(num, 1);
}
public static String addCommas(long num, int counter) {
if (num == 0) {
return ""; // base case ends recursion
}
else {
long digit = num % 10;
num = num / 10;
String comma = (counter%3==0 && num>0) ? "," : "";
// recursive call below because we call addCommas() again
return addCommas(num, counter+1) + comma + digit;
}
}
}
Here's a compact solution to the second problem:
a method takes a single positive integer and displays the result of
reversing its digits
public static String reverseDigits(long num) {
if (num == 0) {
return "";
}
else {
return String.valueOf(num % 10) + reverseDigits(num / 10);
}
}
I am doing my assignment question which is to "reverse a number keep the leading zeros and remove the trailing zeros also keep the sign as it is".
If I reverse it taking as a integer, it will remove leading as well as trailing zeros and if I reverse it taking as a string, it will keep all the zeros.
Can anyone help me only keeping the leading zeros.
For example "-00360" should be "-6300".
problem-
Write a Java function to accept a number and return the reverse of the same. If the number ends with one or more zeros, then in the reversed number those zeros will not be present (since those zeros become leading zeros). If the input number is negative, the sign should be retained. ##Examples Input: -123 Output: -321 Input: 1123400 Output: 43211
In below codes, you can reverse the negative and positive numbers. On method reversedString(String num), you can reverse your numbers. String reverseNumKeeper() helps you to keep your new reversed number. With using for loop, you reverse the number, 123 => 321. Then, you should check if the new reversed String has a negative sign, if has, you should add it in front of number, else, just return new reversed number.
import java.util.Scanner;
public class Reverse {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter number");
//input
String number = scanner.next();
System.out.println(Reverse.reversedString(number));
}
private static String reversedString(String num) {
String reverseNumKeeper = "";
//reverse number with and without negative sign
for (int i = num.length(); i > 0; i--) {
reverseNumKeeper += num.charAt(i - 1);
}
//check if reverseNumKeeper has a negative sign or not
if (reverseNumKeeper.contains("-")) {
return "-" + Integer.parseInt(reverseNumKeeper.replace("-", ""));
} else {
return "" + Integer.parseInt(reverseNumKeeper);
}
}
}
Well as YCF_L said you can just use a StringBuilder having a negative there does not make to much difference. You can include a check for it.
public class FunWithNumbers {
public static int numberReverser(String number) {
System.out.println("Input: " + number);
int returnVal;
String returnString;
boolean negative = false;
//If minus is always at the start if it is there
if(number.substring(0, 1).equals("-")) {
negative = true;
}
if(negative) {
returnString = new StringBuilder(number.substring(1, number.length() - 1)).reverse().toString().replaceFirst("^[0]+", "");
returnString = "-" + returnString;
} else {
returnString = new StringBuilder(number).reverse().toString().replaceFirst("^[0]+", "");
}
try {
returnVal = Integer.parseInt(returnString);
} catch (NumberFormatException nFE) {
System.out.println("There was a number format exception");
returnVal = -1;
}
System.out.println("Output: " + returnVal + "\n");
return returnVal;
}
public static int numberReverser(int number) {
return numberReverser(Integer.toString(number));
}
public static void main(String[] args) {
//Usage
FunWithNumbers.numberReverser("003600");
FunWithNumbers.numberReverser("-003600");
FunWithNumbers.numberReverser((int)0036000D);
FunWithNumbers.numberReverser((int)-003600D);
}
}
Output
Input: 003600
Output: 6300
Input: -003600
Output: -6300
Input: 36000
Output: 63
Input: -3600
Output: -63
You might notice that there are two ways of inputting it here, but only one will give you the correct output you are after.
The first way if with a String. This provides the expected output. The second method, with an int does not provide the expected output. This is because an int will not store the leading zeros. Similarly, if you attempt to input an int with leading zeros, you can actually convert it to octal. To avoid this you can use (int)<int>D or (int)<int>F. See the example in the code
I'm trying to write an application that inputs a dollar amount to be printed on a check, I'm having trouble figuring out how to print out the number in a check protected with leading **** asterisks.
Here's the code I have so far
import java.text.DecimalFormat;
import java.util.Scanner;
import java.text.NumberFormat;
import java.util.Locale;
public class CheckProtection
{
private static double maxAmount = 1000;
public static void main (String args [])
{
//System.out.printf(checkFormatter.format(check));
//DecimalFormat checker = new DecimalFormat("******.**");
//System.out.println(checker);
boolean validEntry = false;
while (validEntry == false)
{
Scanner userEntry = new Scanner(System.in);
System.out.println("Enter The check amount under a $1000.00 and greater that 0.");
if (userEntry.hasNextDouble() == true)
{
double check = userEntry.nextDouble();
if (check > 0)
{
if(check < maxAmount)
{
validEntry = true;
NumberFormat checkFormatter = NumberFormat.getCurrencyInstance();
checkFormatter.format(check);
System.out.printf("%5s",+ check);
}
}
}
}
}
Edit: With the sample inputs and expected output given in the comment, my previous answer was not correct.
Given each of those inputs, this update should produce the expected output:
String value = "$" + String.format("%.2f", check);
System.out.println(value);
String check_fmt = ("*********" + value).substring(value.length());
System.out.println(check_fmt);
Note: borrowed ingenuity from this answer
old answer: Not sure if it could be done with printf(), but String.format works,
String result = String.format("%6.2f", check); // 6 spaces width, 2 spaces precision, 'f' converts the double
System.out.println(result.replace(" ", "*"));
Note: used 6 spaces width = 3 spaces for whole dollar + 2 spaces for cents + 1 space for decimal
The requirement is to check if the number of digits is less than 7 digits in that case insert in DB else don't. I have tried the following solutions:
First solution:
public static void checkNoOfDigitVal(BigDecimal bigDecVal) {
BigInteger digits = bigDecVal.toBigInteger();
BigInteger ten = BigInteger.valueOf(10);
int count = 0;
do {
digits = digits.divide(ten);
count++;
} while (!digits.equals(BigInteger.ZERO));
System.out.println("Number of digits : " + count);
}
First solution works fine sometimes but sometimes the condition in while loop is not satisfied and it keeps on increasing the count number leading to endless count.
Second solution:
public static void checkNoOfDigitsVal(BigDecimal bigDecVal) {
String string = bigDecVal.toString();
String[] splitedString = string.split("\\.");
String[] newVal = splitedString[0].split("");
int a = newVal.length - 1;
if (a <= 6) {
System.out.println("correct size insert into DB: " + a);
} else {
System.out.println("Incorrect size insert cancel: " + a);
}
}
For example, if the value is 999999.9999, the second solution will return newVal.length = 6.
Please suggest a better solution to check the number of digits for big decimal where looping overhead can be minimized.
You can get it trivially using:
static int integerDigits(BigDecimal n) {
n = n.stripTrailingZeros();
return n.precision() - n.scale();
}
The precision is the total number of digits, and the scale is how many of those are to the right of the decimal point, so the difference is how many are to the left of the decimal point.
EDIT it's necessary to remove any trailing zeros to get a correct result for e.g. 0.000
EDIT 2 alternatively (and acks to #AdrianShum), since the problem with trailing zeroes only manifests itself with 0.00... you could use:
static int integerDigits(BigDecimal n) {
return n.signum() == 0 ? 1 : n.precision() - n.scale();
}
Live demo at http://ideone.com/uI6iMG
There's a much better solution in Alnitak's answer, posted just after mine (but which I've only seen now). I guess I'll leave this since a couple of people have found it useful, but if I needed to do this, I'd use their approach, not the approach below.
Your second solution is close, but it doesn't have to be quite that complicated:
public static void checkNoOfDigitsVal(BigDecimal bigDecVal) {
String str = bigDecVal.toString();
int wholeNumberLength = str.split("\\.")[0].length();
if (wholeNumberLength <= 6) {
System.out.println("correct size insert into DB: " + wholeNumberLength);
} else {
System.out.println("Incorrect size insert cancel: " + wholeNumberLength);
}
}
Live Example
I'm assuming that your 999999.999 example should result in wholeNumberLnegth of 6 and therefore be inserted in the DB (the question is unclear about that).
Because the current answers are not robust enough IMO, Here's my solution.
This method will scale a BigDecimal to the given length, but only scales the fractional part. It will throw an Exception if the integer part will be scaled. For my use case this is what I want. Tweak it to your liking.
public static BigDecimal scaleBigDecimalToLength(BigDecimal bigDecimal, int length) throws NumbersUtilException {
int digitCount = bigDecimal.toPlainString().replaceAll("[.,-]", "").length();
if (digitCount > length) {
int scale = bigDecimal.scale();
int newScale = length - (digitCount - scale);
if (scale > 0 && newScale >= 0) {
bigDecimal = bigDecimal
.setScale(length - (digitCount - scale), RoundingMode.HALF_UP);
} else {
throw new NumbersUtilException(
String.format("Cannot scale %s to a length of %s", bigDecimal, length));
}
}
return bigDecimal;
}
scaleBigDecimalToLength(BigDecimal.valueOf(0.0000012345600000), 8)
Output: 0.0000012
If you want to ignore the Dot (".") and count. then try this :
int count = 0;
BigDecimal bigDecimal = new BigDecimal("123.1000");
String[] split = bigDecimal.toString()
.split("\\.");
for (String element : split) {
count = count + element.length();
}
System.out.println("Total digits are " + count);
My question is :
How do I make the program print the number of digits before the decimal point and how many comes after a number.
public class Strings {
public static void main(String args[])
{
double number = 17.0/3;
DecimalFormat number_format = new DecimalFormat("#.###");
System.out.println(number);
String formatted_string = number_format.format(number);
System.out.println(formatted_string);
}
}
I need the number of integers before decimal point
I need to get result of 1 and 3.
Number of digits before the decimal point - DecimalFormat#setMaximumIntegerDigits It does the job -
double number = (double)17/3;
java.text.DecimalFormat number_format = new java.text.DecimalFormat("#.###");
number_format.setMaximumIntegerDigits(0);
System.out.println(number);
String formatted_string = number_format.format(number);
System.out.println(formatted_string);
Result :
5.666666666666667
.667
or a more simpler way
double d = 17.0/3;
System.out.format("%1.2f", d);
just try this
double d = 15.0/4; // Assuming a number
String ds = String.valueOf(d); // converting it into string (it will be 3.75)
String arr[] = ds.split("\\D"); // splitting by non number charecter (in our case its dot)
// So array containts ["3", "75"] strings
System.out.println("Before Decimal point: "+ arr[0].length()); // length gives number of digits
System.out.println("After Decimal point: "+ arr[1].length());
The easiest way to do this would be to convert the number to a string and then to split the string based on the '.' separator. Then split the first array element with "". The length of this array would give you your answer.
// number = some_number.some_more_numbers;
String value = number + ""; // convert to string
String[] parts = value.split(".");
String[] numbers = parts[0].split("");
int length = numbers.length; // Gives number of individual numbers before decimal point
I hope this helps.