999 to 999
1000 to 1k
1500000 to 1.5m
and so on, I would like to not lose any precision at all
Also, need to convert them back to their original value
1.5m to 1500000
etc
The highest it would go is 11 digits max
Thanks
How about this:
import static java.lang.Double.parseDouble;
import static java.util.regex.Pattern.compile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
...
private static final Pattern REGEX = compile("(\\d+(?:\\.\\d+)?)([KMG]?)");
private static final String[] KMG = new String[] {"", "K", "M", "G"};
static String formatDbl(double d) {
int i = 0;
while (d >= 1000) { i++; d /= 1000; }
return d + KMG[i];
}
static double parseDbl(String s) {
final Matcher m = REGEX.matcher(s);
if (!m.matches()) throw new RuntimeException("Invalid number format " + s);
int i = 0;
long scale = 1;
while (!m.group(2).equals(KMG[i])) { i++; scale *= 1000; }
return parseDouble(m.group(1)) * scale;
}
If they weren't final you could extend java.lang.Integer etc. to override the toString() method. Is it worth creating a java.lang.Number subclass? Probably not. You could create your own classes: MyInteger, MyFloat etc using composition (they'll have an attribute to hold the numeric value) and override the toString() method to return the formats you want.
For the other way around, you could create factory methods in your MyXXX classes that creates objects containing the numeric value of the string (such as "1m").
The good thing is that kind of work lends itself well for unit testing.
You could probably obtain what you want by using directly a NumberFormat subclass but depending on how you're going to use it, the above design could be better.
static String[] prefixes = {"k","M","G"};
// Formats a double to a String with SI units
public static String format(double d) {
String result = String.valueOf(d);
// Get the prefix to use
int prefixIndex = (int) (Math.log10(d) / Math.log10(10)) / 3;
// We only have a limited number of prefixes
if (prefixIndex > prefixes.length)
prefixIndex = prefixes.length;
// Divide the input to the appropriate prefix and add the prefix character on the end
if (prefixIndex > 0)
result = String.valueOf(d / Math.pow(10,prefixIndex*3)) + prefixes[prefixIndex-1];
// Return result
return result;
}
// Parses a String formatted with SI units to a double
public static double parse(String s) {
// Retrieve the double part of the String (will throw an exception if not a double)
double result = Double.parseDouble(s.substring(0,s.length()-1));
// Retrieve the prefix index used
int prefixIndex = Arrays.asList(prefixes).indexOf(s.substring(s.length()-1)) + 1;
// Multiply the input to the appropriate prefix used
if (prefixIndex > 0)
result = result * Math.pow(10,prefixIndex*3);
return result;
}
Related
Not sure if I'm doing this right, but this is a continuation of the program I was working on here...Homework Help PT1
I'm struggling a lot with this homework assignment...
**(Math: The Complex class) A complex number is a number in the form a + bi,
where a and b are real numbers and i is 2-1. The numbers a and b are known
as the real part and imaginary part of the complex number, respectively. You can
perform addition, subtraction, multiplication, and division for complex numbers
using the following formulas:
a + bi + c + di = (a + c) + (b + d)i
a + bi - (c + di) = (a - c) + (b - d)i
(a + bi)*(c + di) = (ac - bd) + (bc + ad)i
(a + bi)/(c + di) = (ac + bd)/(c2 + d2) + (bc - ad)i/(c2 + d2)
You can also obtain the absolute value for a complex number using the following
formula:
a + bi = 2a2 + b2
Design a class named Complex for representing complex numbers and the
methods add, subtract, multiply, divide, and abs for performing complexnumber
operations, and override toString method for returning a string representation
for a complex number. The toString method returns (a + bi) as a
string. If b is 0, it simply returns a. Your Complex class should also implement the
Cloneable interface.
Provide three constructors Complex(a, b), Complex(a), and Complex().
Complex() creates a Complex object for number 0 and Complex(a) creates
a Complex object with 0 for b. Also provide the getRealPart() and
getImaginaryPart() methods for returning the real and imaginary part of the
complex number, respectively.
Write a test program that prompts the user to enter two complex numbers and
displays the result of their addition, subtraction, multiplication, division, and absolute
value.**
Here is what I have so far. Two classes...
// ComplexTest.java
import java.util.Scanner;
public class ComplexTest {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter the first complex number: ");
double realPart = input.nextDouble();
System.out.println("Enter the second complex number: ");
double imaginaryPart = input.nextDouble();
Complex cn1 = new Complex(realPart, imaginaryPart);
Complex cn2 = new Complex(realPart);
Complex cn3 = new Complex();
if (realPart == 0) {
System.out.println(cn3.toString());
}
if (imaginaryPart == 0) {
System.out.println(cn2.toString());
}
if(realPart != 0 && imaginaryPart != 0) {
System.out.println(cn1.toString());
}
}
}
// Complex.java
import java.util.Scanner;
public class Complex {
// cloneable interface
public interface Cloneable { }
// Instance Real + Getters and Setters (Accessors and Mutators)
private double realPart;
public double getReal() {
return realPart;
}
public void setReal(double real) {
this.realPart = real;
}
// Instance Real + Getters and Setters (Accessors and Mutators)
private double imaginaryPart;
public double getImaginary() {
return imaginaryPart;
}
public void setImaginary(double imaginary) {
this.imaginaryPart = imaginary;
}
// Constructor Method CN1
public Complex(double a, double b) {
realPart = a;
imaginaryPart = b;
}
// Constructor Method CN2
public Complex(double a) {
realPart = a;
imaginaryPart = 0;
}
// Constructor Method CN3
public Complex() { }
// Add Complex Numbers
public Complex add(Complex comp1, Complex comp2) {
double real1 = comp1.getReal();
double real2 = comp2.getReal();
double imaginary1 = comp1.getImaginary();
double imaginary2 = comp2.getImaginary();
return new Complex(real1 + real2, imaginary1 + imaginary2);
}
// Subtract Complex Numbers
public Complex subtract(Complex comp1, Complex comp2) {
double real1 = comp1.getReal();
double real2 = comp2.getReal();
double imaginary1 = comp1.getReal();
double imaginary2 = comp2.getReal();
return new Complex(real1 - real2, imaginary1 - imaginary2);
}
// Multiply Complex Numbers
public Complex multiply(Complex comp1, Complex comp2) {
double real1 = comp1.getReal();
double real2 = comp2.getReal();
double imaginary1 = comp1.getReal();
double imaginary2 = comp2.getReal();
return new Complex(real1 * real2, imaginary1 * imaginary2);
}
// Divide Complex Numbers
public Complex divide(Complex comp1, Complex comp2) {
double real1 = comp1.getReal();
double real2 = comp2.getReal();
double imaginary1 = comp1.getReal();
double imaginary2 = comp2.getReal();
return new Complex(real1 / real2, imaginary1 / imaginary2);
}
// toString to Change Display
public String toString() {
String result;
result = realPart + " + " + imaginaryPart + "i";
return result;
}
}
Here is my updated code after Jan's help. I've created 3 more methods (subtract, multiply and divide). Should I not be using comp1 and comp2 in every method and instead name them separately from each other? The goal is to print the results of each method at the end at the same time. Will these having the same names mess with that?
I'd also like to know when I should implement the cloneable interface.
Lastly, according to the text a complex number actually looks like two numbers separated by a space. (i.e. 3.5 5.0 rather than just 3.5). If I add two more scanner inputs for the second halves of both of complex numbers, I will have to change my code. Will I have to create new getters and setters to receive this number? Such as imaginaryPart2 and realPart2?
Thank you again for all of the help.
Some Topics to dwell upon:
Variable Scope
Parameters passed into a method are visible only throughout that method. So naming your two operands comp1 and comp2 for each and all of your methods is perfectly fine.
But:
Object Orientation
Your methods should only have one parameter. Say your have one instance of Complex named x. And you want to add to that another instance named y. Then given your code, any operation of x.add(x,y) and y.add(x,y) and even z.add(x, y) would yield the same results.
So: Drop one of your paramters. You might want to add nullchecks.
public Complex add(Complex toAdd) {
return new Complex(this.realPart + toAdd.realPart,
this.imaginaryPart + toAdd.imagineryPart);
}
Now you can write
Complex z = x.add(y);
Getters and Setters
As your add / subtract / divide / multiply operations all return a new Complex number, you might want to make Contex immutable - that is: Provide no setters. Complex number can be created through the constructors. You can get new Complex numbers by invoking calculations on existing ones. But you cannot change a number.
So my advice: Remove the setters.
Input of complex numbers
Instead of reading doubles, you might want to think about reading a String and match that string with a regular expression. You could use that as a utility method in your main or even as a consttructor for Complex, allowing to use a String as input.
Consider this method for matching String:
Pattern complexFinder = Pattern.compile("(-?\\d+(\\.\\d*)?)?\\s*([-+]\\s*\\d+(\\.\\d*)?i)?");
Matcher m = complexFinder.matcher(complexString);
if (m.find()) {
double realPart = 0;
double imaginaryPart = 0;
if (m.group(1) != null) {
realPart = Double.parseDouble(m.group(1).replaceAll("\\s", ""));
}
if (m.group(3) != null) {
imaginaryPart = Double.parseDouble(m.group(3).replaceAll("\\s", "").replace("i", ""));
}
Complex c = new Complex(realPart, imaginaryPart);
}
Cloneable
Cloneable is an interface you add to your class declaration:
public class Complex implements Cloneable {
Additionally you should implement a clone() method:
public Object clone() {
return super.clone();
}
toString()
Your assignment requests that an 0 imaginary part be left out in String output. So you might want to check that again. This should be a simple if()
What am I doing wrong?
The median is always -0.5 result or 0.5, if ((m) + (m+1))/2;
public static double mediana(List<Double> liczby ){
Collections.sort(liczby);
int n = liczby.size()/2;
double m;
m = get(n);
if (liczby.size() % 2 == 0){
return ((m) + (m-1))/2;
}
else {
return m;
}
}
In your code, the problem is in this line.
return ((m) + (m-1))/2;
It should return the average of nth number and (n-1)th number as n = (size of the list)/2. You can try this.
public static double mediana(List<Double> liczby ){
Collections.sort(liczby);
int n = liczby.size()/2;
double m;
if (liczby.size() % 2 == 0)
m = (liczby.get(n) + liczby.get(n-1))/2;
else
m = liczby.get(n);
return m;
}
I believe the problem with it is the line return ((m) + (m-1))/2; You forget to retrieve the input of the next element in the list. Try:
l = get(n+1);
return (m + l)/2;
instead of:
return ((m) + (m-1))/2;
You need to be retrieving the n and n-1-th elements. You are currently subtracting 1 from the n-th value, which is not meaningful:
return (get(n) + get(n-1)) / 2;
I faced the same problem yesterday and I wrote a solution similar to sifho's one.
My method---implemented using Java generics---calculates the median value on every collection of Numbers. You can use the method with collections of Doubles, Integers, Floats and returns a double. Please consider that my method creates another collection in order to not alter the original one.
I provide also a test, have fun. ;-)
public static <T extends Number & Comparable<T>> double median(Collection<T> numbers){
if(numbers.isEmpty()){
throw new IllegalArgumentException("Cannot compute median on empty array of numbers");
}
List<T> numbersList = new ArrayList<>(numbers);
Collections.sort(numbersList);
int middle = numbersList.size()/2;
if(numbersList.size() % 2 == 0){
return 0.5 * (numbersList.get(middle).doubleValue() + numbersList.get(middle-1).doubleValue());
} else {
return numbersList.get(middle).doubleValue();
}
}
JUnit test code snippet:
/**
* Test of median method, of class Utils.
*/
#Test
public void testMedian() {
System.out.println("median");
Double expResult = 3.0;
Double result = Utils.median(Arrays.asList(3.0,2.0,1.0,9.0,13.0));
assertEquals(expResult, result);
expResult = 3.5;
result = Utils.median(Arrays.asList(3.0,2.0,1.0,9.0,4.0,13.0));
assertEquals(expResult, result);
}
Usage example (consider the class name is Utils):
List<Integer> intValues = ... //omitted init
Set<Float> floatValues = ... //omitted init
.....
double intListMedian = Utils.median(intValues);
double floatSetMedian = Utils.median(floatValues);
I do not know how to look method get(n).
It generates automatically.
The method can not return to zero.
private static double get(int n) {
// TODO Auto-generated method stub
return 0;
}
I'm trying to get a better understanding of ZFC set theory, in particular how a computer program might model the axiom of infinity to "construct" natural numbers. The typical symbols I've seen used to construct the natural numbers are: "{", "}", and ",". The code below works, but I'm hoping for a purely recursive solution. One that given a natural number (here using int), recursively builds up the corresponding string into its set-theoretic encoding and then returns it. Ideally, I hope for it to work without using any extra data structures like the String array currently being used.It's ok if the runtime is slow (exponential). Using recursion sometimes makes the expression of the process simpler, more condensed/elegant and easier to understand, and I would very much like to see what such a solution for this might look like, regardless of performance. Ultimately, I'd like a better understanding of foundations of math/numbers. I have many questions but thought this might be a good way to begin. Thanks!
// Converts an natural number to its ZFC set notation:
// 0 = {}, 1 = {0} = {{}}, 2 = {0,1} = {{},{{}}},
// 3 = {0,1,2} = {{},{{}},{{},{{}}}} ...
import java.util.Scanner;
public class IntToSetNotation {
private static final String openBrace = "{";
private static final String closeBrace = "}";
private static final String seperator = ",";
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt();
System.out.println(getSetNotationFromInt(n));
}
private static String getSetNotationFromInt(int n) {
String[] nums = new String[n+1];
nums[0] = openBrace + closeBrace;
for (int i = 1; i < nums.length; i++) {
if(i == nums.length-1)
nums[i] = openBrace + getPrevSets(i,nums) + closeBrace;
else
nums[i] = seperator + openBrace + getPrevSets(i,nums) + closeBrace;
}
return nums[n];
}
private static String getPrevSets(int n, String[] nums) {
String s = "";
for (int i = 0; i<n; i++)
s += nums[i];
return s;
}
}
So recursion sounds really difficult, but it's actually kind of simple once you get over the name.
Recursion needs to things: a base case to stop recursing, and an output to do what you want.
Say you want to write a recursive problem that takes in a number x, and returns a specific pattern of curly braces:
0 == (nothing)
1 == {}
2 == {{}}
3 == {{{}}}
...
So, your recursive method is going to take one integer.
Now, lets look at the method output. If we call the recursive method on 1, we want to return {}. Easy. In terms of java, we'll be returning a string.
Great, now we know the return type of the method.
If we call recursive method on 2, we want the method to first output {}, and then we want the method to execute AGAIN, but this time, we are putting a curly AT THE BEGINNING, and one curly AT THE END.
This is the part that is hard to explain. Imagine recursion as a loop. Eventually, we want the recursion to terminate. Say we call the method initially on 3. We want {{{}}} to be returned. First, our method will return {}, followed by {{}}, then {{{}}}. It runs a total of 3 times.
In the recursive call, you have to call it one less than the initial call.
Ok, now you say, if we are subtracting 1 each time and calling the method again, how do we get it to stop?
That's called the base case. If the method is called on 0, we don't want to return anything, thus we want to exit out of the method with a simple return statement.
Apply this to your own problem, and you should be good.
String exampleRecursiveMethod(int x){
if(x==0)return "";
else return exampleRecursiveMethod(x-1)
}
This is an example to get you started. The return statement after the else is called the recursive call, I talked about it above.
I came up with the below code as a recursive solution. It works, but I wonder if there is anyway to streamline it, perhaps to use less methods? Any thoughts or comments are welcome.
public class IntToSetNotationRecursive {
private static final String openBrace = "{";
private static final String closeBrace = "}";
private static final String seperator = ",";
public static void main(String[] args) {
for (int i = 0; i < 6; i++) {
System.out.println(i + " = " + getSetNotationFromInt(i));
}
}
static String getSetNotationFromInt(int n){
return helper1(n, n, "");
}
static String helper1(int n, int x, String s){
if(x<=0)
return openBrace + s + closeBrace;
return helper1(n, x-1, helper2(x-1) + ((x != n ) ? seperator : "") + s);
}
static String helper2(int x){
if(x<=0)return openBrace+closeBrace;
else return helper1(x, x, "");
}
}
Prints:
0 = {}
1 = {{}}
2 = {{},{{}}}
3 = {{},{{}},{{},{{}}}}
4 = {{},{{}},{{},{{}}},{{},{{}},{{},{{}}}}}
5 = {{},{{}},{{},{{}}},{{},{{}},{{},{{}}}},{{},{{}},{{},{{}}},{{},{{}},{{},{{}}}}}}
The second helper method isn't necessary. Here is a shortened version.
public class IntToSetNotationRecursive {
private static final String openBrace = "{";
private static final String closeBrace = "}";
private static final String separator = ",";
public static void main(String[] args) {
for (int i = 0; i < 6; i++) {
System.out.println(i + " = " + getSetNotationFromInt(i));
}
}
static String getSetNotationFromInt(int n){
return helper1(n, n, "");
}
static String helper1(int n, int x, String s){
if(x<=0)
return openBrace + s + closeBrace;
return helper1(n, x-1, helper1(x-1,x-1,"") + ((x != n ) ? separator : "") + s);
}
}
Prints:
0 = {}
1 = {{}}
2 = {{},{{}}}
3 = {{},{{}},{{},{{}}}}
4 = {{},{{}},{{},{{}}},{{},{{}},{{},{{}}}}}
5 = {{},{{}},{{},{{}}},{{},{{}},{{},{{}}}},{{},{{}},{{},{{}}},{{},{{}},{{},{{}}}}}}
I have a method that is converting a decimal (double value) into a fraction and putting the numerator and denominator values into an int[] of size 2.
Testing it works out fine for most values except when I hit 0.0001. Then the return value is 1.0/1.0.
The method:
private static int[] toFractionPos(double x){
String[] parts = Double.toString(x).split("\\.");
double den = Math.pow(10, parts[1].length()); //denominator
double num = Double.parseDouble(parts[0]) * den + Double.parseDouble(parts[1]); //numerator
return reduceFraction((int)num, (int)den);
}
reduceFraction() method:
public static int[] reduceFraction(int num, int den){
int gcf = GCF(num, den); //greatest common factor
int[] rf = {num/gcf, den/gcf};
return rf;
}
Thanks!
The algorithm seems fine. However, using double is not suitable for this kind of problem, because precision decreases as the scale grows.
You should use BigDecimal and BigInteger instead. I've roughly modified your example so that it works with them, but I haven't taken care of details, i.e. parsing the String shouldn't be necessary since scale can be retrieved from a BigDecimal with a getter, you can configure different rounding modes, etc:
import java.math.BigDecimal;
import java.math.BigInteger;
public class Sample {
static int[] toFractionPos(BigDecimal x) {
String[] parts = x.toString().split("\\.");
BigDecimal den = BigDecimal.TEN.pow(parts[1].length()); // denominator
BigDecimal num = (new BigDecimal(parts[0]).multiply(den)).add(new BigDecimal(parts[1])); // numerator
return reduceFraction(num.intValue(), den.intValue());
}
static int[] reduceFraction(int num, int den) {
int gcd = BigInteger.valueOf(num).gcd(BigInteger.valueOf(den)).intValue(); // greatest
// common
// divisor
int[] rf = { num / gcd, den / gcd };
return rf;
}
public static void main(String[] args) {
int[] fraction = toFractionPos(new BigDecimal("0.0001"));
System.out.println(fraction[0] + "/" + fraction[1]); // 1/10000
}
}
Note: optimizations left as an excercise ;)
You shouldn't work with doubles as you are losing precision and this can lead to serious errors. But in the case of 1.0001 the problem is that:
Double.toString(1.0001) == "1.0E-4"
Then you try to parse "0E-4" and you get 0 instead of 1. You could do the following if you expect at most 10 decimal points:
DecimalFormat df = new DecimalFormat("0",
DecimalFormatSymbols.getInstance(Locale.ENGLISH));
df.setMaximumFractionDigits(10);
String[] parts = df.format(x).split("\\.");
How about this?
private static int[] toFractionPos(double x){
int den = (int)Math.pow(10,(int)Math.log10(Integer.MAX_VALUE));
int num = (int)(x*den);
return reduceFraction(num, den);//this came from your code
}
I think this will work,
public int[] Fraction(double n) {
BigDecimal p = BigDecimal.ONE;
BigDecimal dn = BigDecimal.valueOf(n);
while(true){
dn = dn.multiply(p);
if( dn.compareTo(new BigDecimal(dn.toBigInteger()))==0 )
break;
else
p = p.multiply(BigDecimal.TEN);
}
BigInteger num=dn.toBigInteger(), den=p.toBigInteger(), g=num.gcd(den);
num = num.divide(g);
den = den.divide(g);
int[] res = new int[2];
res[0] = num.intValue();
res[0] = den.intValue();
return res;
}
Help me please for the next problem:
There is String pattern, assume it's public final static variable. There is string where we search. There is class, simple wrapper to double
public class Wrapper {
private double value;
public double getValue() {
return value;
}
public Wrapper(double value) {
this.value = value;
}
}
I need method
public Wrapper parse(String s, int index)
which returns Wrapper's object if string at the index is double number with maximum 2 digits after decimal point(if there is decimal point at all) and right after number ends there is String pattern after it
For example for strings
String pattern = "money";
String search = "Giveme10.25moneyplease";
parse(search, 6) returns new Wrapper(10.25)
In other cases (index less then zero, greater then length of the string, substring that starts from index isn't number at all or it's double number but it contains more then 2 digits after decimal point or there is no string pattern after number) method must return null
And another method that differs only string pattern must be first and then double number with maximum 2 digits after decimal point and all other the same
String pattern = "money"
String s = "Ihavemoney10.50"
parse1(s, 5) returns new Wrapper(10.50)
You can use DecimalFormat along with ParsePosition like this
import java.text.DecimalFormat;
import java.text.ParsePosition;
public class TestP {
public static void main(String[] args) {
DecimalFormat decimalFormat = new DecimalFormat("00.##'money'");
String search = "Giveme10.25moneyplease";
int index = 6;
//output 10.25
Number number = decimalFormat.parse(search, new ParsePosition(index));
if (number != null) {
String s = number.toString();
if (s.contains(".") && s.length() > 5) {
number = null;
}
}
System.out.println(number);
}
}