decimal number to utf-8 rational number in Java - java

i want to change 2.5 to 2½. Not sure how to change it.
Let say I have “AMZN 2½ 22” in a long text that I have to highlight in java swing textpane but I have values in three variable as below
A = AMZN
B = 2.5
C = 22
Based on this value I will not be able to match so changing B to Rational number (String) and then matching and it’s working fine but I don’t want to do this… it’s just a temp fix.
Can someone help me ?
B = B.toString().replace(".25", "¼")
.replace(".5", "½")
.replace(".75", "¾")
.replace(".375", "⅜")
.replace(".625", "⅜")
.replace(".125", "⅛")
.replace(".875", "⅞")
.replace(".0", "")
.replace(".000", "")
.replace(".00", "");
Thanks

Here's how to print the symbol 'half':
String half = "\u20BD";
System.out.println("2" + half);
determining if a number is an integer plus half is left as an exercise to the reader.

You can swap .0 replaces with a regex (replaceAll("\\.[^1-9]+","" comes to mind), you can move the replaces to a map or utility class, have them happen only when Float.parseFloat(var) doesn't throw NumberFormatException...
But there is no truly better way to do such arbitrary replaces. Those unicode strings have no intrinsic connection with the numbers they represent that you could use.

There are two alternatives for real numbers: double (an approximation of a real number) or BigDecimal (maintaining a precission).
String a = "AMZN";
BigDecimal b = new BigDecimal("2.5");
double b2 = 2.5;
int c = 22;
// %s = string, %f = floating point, %d = digits, %n = newline.
System.out.printf("%s %f %d%n", a, b2, c);
For double you have not really any control but you might format the output (printf) using "%.3f" for a precission of 3 decimals.
In your case you want to represent the numbers using fractions from the Unicode.
Let's do that with the less suited double:
System.out.printf("%s %s %d%n", a, asFraction(b2), c);
static String[] fractionTexts = { "", "¼", "½", ... }; // Maybe char
static double[] fractionValues = { 0.0, 0.25, .5, ... };
static String asFraction(double x) {
if (x < 0) {
return "\u2212" + asFraction(-x); // U+2212 is Unicode minus.
}
long integralPart = (long)x;
double decimalsPart = x - integralPart;
for (int i = 0; i < fractionValues.length; ++i) {
if (almostEqual(decimalsPart, fractionValues[i]) {
decimalPoint = "";
return MessageFormat("{0}", integralPart) + fractionTexts[i];
}
}
return MessageFormat("{0}", x);
}
private boolean almostEqual(double x, double y) {
final double EPS = 0.0001;
return x >= y - EPS && x <= y + EPS;
}
The code uses MessageFormat for thousand separators / decimal separator. For 0.0, 0.00, 0.00ß0 (the same number) it leaves away the numbers explicitly. The java source code must be in the same encoding as the java compiler and be able to hold ¼ and others (like UTF-8).
For the error bearing double I have introduced almostEqual.

Related

How do I replace the first three characters of a Java integer by 111?

I have an integer in java. How do I replace its’ first three numbers with 111(or any other number), for example turning 783729 into 111729?
Many thanks!
You could convert it into a string and then replace the first three letters.
String s = String.valueOf(783729);
int i = Integer.parseInt(s.replace(s.substring(0, 3), "111"));
Convert the integer to string replace the first three characters and convert it back to integer.kindly try to do it yourself. if you feel stuck during coding post your code along with the problem you face.
You can do this without converting to a string using simple arithmetic:
// Assumes that num is initially at least 999.
int replaceWith111(int num) {
if (num < 1000) {
return 111;
}
return 10 * replaceWith111(num / 10) + (num % 10)
}
Obviously if you just need to get this done you'd convert to String and do the substitution there.
However, just for fun, here's how you could do it using only Math functions and operators. Doesn't handle negative numbers - that's left as an exercise fo the reader :)
int s = 111;
int n = 783729;
int ds = (int)Math.ceil(Math.log10(s));
int dn = (int)Math.ceil(Math.log10(n));
int b = (int)Math.pow(10, dn-ds);
int sn = s * b + n % b;
System.out.println(sn);
Output:
111729

Calculating a BigDecimal results in inaccurate answer

So I just wanted to screw around to see if I can make it so I can calculate E, but instead have it so I can have dynamic degrees of precision. While I did technically accomplish it, no matter what int i put in for the variable PRECISION, the last few numbers are always different from what the actual value of E is suppose to be. I'm not entirely sure why, but help would be appreciated.
import java.math.BigDecimal; //To use for calculating E
public class ComputeE {
public static double calcDenominator(int n)
{
double denominator = 1.0; //Start the BigInt with 1
for(int i = 1; i < n; i++) // Run n-1 amount of times
{
denominator = denominator * i; // Multiply BigInteger by the BigInteger obtained with the int value i
}
return denominator;
}
public static void main(String[] args) {
BigDecimal e = new BigDecimal(0.0);
int PRECISION = 15;
int iterations = 0;
for(int i = 0; i < PRECISION; i++)
{
iterations++;
BigDecimal numerator = new BigDecimal(1.0); // to divide, we need two BigDecimals, the numerator is 1
BigDecimal factorial = new BigDecimal(calcDenominator(i)); // the denominator is i! which we get from calling the factorial method
factorial = numerator.divide(factorial, PRECISION, BigDecimal.ROUND_UNNECESSARY); // compute 1/i!, note divide is overloaded, this version is used to
// ensure a limit to the iterations when division is limitless like 1/3
e = e.add(factorial); // add the latest 1/i! to e
}
System.out.println("Computed value of e : " + e);
System.out.println("Expected value of e : " + Math.E);
}
}
Rounding is necessary here. Use something like HALF_EVEN. Even better, use the enum value RoundingMode.HALF_EVEN, because the integer constants for rounding mode are deprecated.
In calcDenominator, change your for loop condition to i <= n, or else you'll add 1 one too many times in main and you'll get a value that's 1 too high.
You can use BigDecimal.ONE to initialize numerator. This doesn't affect the result, but why create an unnecessary object? Same comment on the initialization of e, except with BigDecimal.ZERO.
You are using the first PRECISION terms of an infinite series (Maclaurin Series) that approximates e, an irrational number. There is an error term when you cut off the for loop, and that is expected mathematically. With the above changes, and bumping PRECISION to 50, I get the following, which looks sufficiently precise.
Computed value of e : 2.71828182845904523536028747135266249775496954201584
Expected value of e : 2.718281828459045
It is precise, despite using the double constructor for BigDecimal because the significant digits for a double start with the first non-zero bit, so even if you're calculating 1/n! for large n, the significant digits are good enough for adding to the existing approximation for e.

Java Integer to Binary Converter Code

I am trying to write a basic calculator. One of the things I want my calculator to have is a base arithmetic converter that gives an output when you input a base 10 integer.
I tried to write code for it on my own and it took nearly 3 hours just to figure out how to convert a number to a given base and it works good enough so far but I have one problem - when I try to convert an integer to base 2 (binary) my calculator does not work for numbers bigger than 1025.
I thought the problem was because there is a max value an integer can hold or something so I tried "BigInteger" but since it does not support remainder "%" operation I could not make it work.
else if(c.equals("Base")) {
g = 0;
l = 0;
System.out.println("Enter the number (Integer) you want to convert");
f = scan.nextInt();
System.out.println("Enter the arithmetic base you want for your new number");
m = scan.nextInt();
for (;f>=1;) {
h=f%m;
f=f/m;
k = (int)Math.pow(10,g);
g++;
l =l + (h*k);
}
System.out.println(l);
}
Sorry if the code is really bad and there are more efficent ways, i just wanted it to be mine instead of looking it up.
If you want to use the BigInteger class, you can use the mod method instead of "%".
BigInteger myBigInteger = new BigInteger("943838859");
System.out.println(myBigInteger.mod(BigInteger.TEN));
This will print 9.
It's not a good idea to store the "binary representation" in an int variable, since that limits you to 10 digits.
Instead, you can use a String variable to hold the result:
String l = "";
while (f > 0) {
h = f % m;
f = f / m;
l = h + l;
}
System.out.println(l);
This is the way I've tried myself (modulo/divide/add):
int decimalOrBinary = 345;
StringBuilder builder = new StringBuilder();
do {
builder.append(decimalOrBinary % 2);
decimalOrBinary = decimalOrBinary / 2;
} while (decimalOrBinary > 0);
System.out.println(builder.reverse().toString()); //prints 101011001
You can do this in a 3 lines of code using a recursive funtion,
public static String convertToBase(int n, int b) {
return n > 0 ? (convertToBase(n / b, b) + n % b) : "";
}

how to create an Exp(-x^2) function?

I am using the "think java" book and I am stuck on exercise 7.6. The goal here is to write a function that can find . It gives you a couple hints:
One way to evaluate is
to use the infinite series expansion:
In other words, we need to add up a series of terms where the ith term
is equal to
Here is the code I came up with, but it is horribly wrong (when compared to Math.exp) for anything other than a power of 1. I don't understand why, as far as I can tell the code is correct with the formula from the book. I'm not sure if this is more of a math question or something related to how big of a number double and int can hold, but I am just trying to understand why this doesn't work.
public static void main(String[] args) {
System.out.println("Find exp(-x^2)");
double x = inDouble("Enter x: ");
System.out.println("myexp(" + -x*x + ") = " + gauss(x, 20));
System.out.println("Math.exp(" + -x*x + ") = " + Math.exp(-x*x));
}
public static double gauss(double x, int n) {
x = -x*x;
System.out.println(x);
double exp = 1;
double prevnum = 1;
int prevdenom = 1;
int i = 1;
while (i < n) {
exp = exp + (prevnum*x)/(prevdenom*i);
prevnum = prevnum*x;
prevdenom = prevdenom*i;
i++;
}
return exp;
} // I can't figure out why this is so inacurate, as far as I can tell the math is accurate to what the book says the formula is
public static double inDouble(String string) {
Scanner in = new Scanner (System.in);
System.out.print(string);
return in.nextDouble();
}
I am about to add to the comment on your question. I do this because I feel I have a slightly better implementation.
Your approach
Your approach is to have the function accept two arguments, where the second argument is the number of iterations. This isn't bad, but as #JamesKPolk pointed out, you might have to do some manual searching for an int (or long) that won't overflow
My approach
My approach would use something called the machine epsilon for a data type. The machine epsilon is the smallest number of that type (in your case, double) that is representable as that number. There exists algorithm for determining what that machine epsilon is, if you are not "allowed" to access machine epsilon in the Double class.
There is math behind this:
The series representation for your function is
Since it is alternating series, the error term is the absolute value of the first term you choose not to include (I leave the proof to you).
What this means is that we can have an error-based implementation that doesn't use iterations! The best part is that you could implement it for floats, and data types that are "more" than doubles! I present thus:
public static double gauss(double x)
{
x = -x*x;
double exp = 0, error = 1, numerator = 1, denominator = 1;
double machineEpsilon = 1.0;
// calculate machineEpsilon
while ((1.0 + 0.5 * machineEpsilon) != 1.0)
machineEpsilon = 0.5 * machineEpsilon;
int n = 0; //
// while the error is large enough to be representable in terms of the current data type
while ((error >= machineEpsilon) || (-error <= -machineEpsilon))
{
exp += error;
// calculate the numerator (it is 1 if we just start, but -x times its past value otherwise)
numerator = ((n == 0) ? 1 : -numerator * x);
// calculate the denominator (denominator gets multiplied by n)
denominator *= (n++);
// calculate error
error = numerator/denominator;
}
return exp;
}
Let me know how this works!

Error in calculating PI in Java with BigDecimal

I have to calculate PI to a certain number of decimals (given in variable zecimale), using the Leibniz formula for calculating PI. I don't know why, but not a single addition or subtraction on that BigDecimal isn't modifying the value of PI.
Why is this?
int zecimale = 0;
if (args.length > 0) {
try {
zecimale = Integer.parseInt(args[0]);
} catch (NumberFormatException e) {
System.err.println("Argument" + " must be an integer");
System.exit(1);
}
}
long start = System.nanoTime();
double numitor = 1;
BigDecimal numitor1 = new BigDecimal(1/numitor);
BigDecimal pi = new BigDecimal(1);
for(int x = 0; pi.scale() <= zecimale; x++)
{
numitor1 = new BigDecimal(1 / numitor);
if(x % 2 == 0)
{
pi.add(numitor1);
}
else
{
pi.subtract(numitor1);
}
BigDecimal doi = new BigDecimal(2);
numitor = numitor + 2;
System.out.println(x);
System.out.println(pi);
}
BigDecimal patru;
patru = new BigDecimal(4);
pi.multiply(patru);
BigDecimal is immutable so the is no way to change it's value. (In the same way String does) This is why all the methods would operate on a BigDecimal return a new BigDecimal as the result
e.g.
pi = pi.add(numitor1);
The second problem is you are using a double in your calculation, defeating the whole point of using a BigDecimal.
The expression pi.scale() should be ~53 after the first iteration and won't get much higher the way ti is written. scale only tells you how many decimal places there are after the dot, not the accuracy of the solution.
You will get better performance if you calculate two expressions in a single loop.
The last problem you have is that each digit takes 10x longer to evaluate, calculating mroe than 15 digits (more than the precision you can get with double) it will take years to complete.

Categories

Resources