How to shift 4 decimal places in a number using DecimalFormat - java

I am trying to convert $11,120.6 million to 1.12 billion. My question is how to shift by 4 decimal places every time after the decimal point since I will be inserting values dynamically in excel.

Original title was a bit misleading, so my answer provides more than one way of accomplishing this task. First part reflects the answer to the new title.
11,120.6 shifted by four decimal places to the left will not create 1.12; more like 1.112 or 1.11 (depending on the number of decimal places). But anyways, here are some thoughts:
DecimalFormat way:
float num = 11120.6;
DecimalFormat numFormat = new DecimalFormat("#.00");
System.out.println(numFormat.format(num));
If it's purely visual, you can just do something like this:
float num = 11120.6;
System.out.println(String.format("%.2f", num));
That one will give you two decimal places to the right of the decimal point, producing 1.11.
Or how about something like this?
float num = 11120.6;
num /= 10000.0;
This will give you 1.11206.
You can create if else logic or something similar to divide/multiple by an appropriate amount, based on the number, i.e.:
if (num >= 10)
{
num /= 10.0;
}
else if (num >= 100)
{
num /= 100.0;
}
...etc...
You can also do something like this along with the similar logic to above:
BigDecimal num = new BigDecimal("11120.6");
num = num.movePointRight(-4);
Unless someone can think of a better way you'll also need to know that the number before was in millions representation and the new number is in billions. Store it in a separate variable as an enumeration, perhaps.
Something else you can do, but it's not very efficient, is what we did in my C++ class in college when we were messing around. You can create several arrays or lists (depending on what it is that you do) for certain number sizes. When you want to display a number of say... listBillions, you'd divide any number from that list by 1000000000.0, or format it as a string. So, in the the end you have your lists of dozens, hundreds, thousands, etc., and you'll always know that listBillions[i] can be nothing but a billion in whatever form it is being displayed.

Related

How do I store astronomically huge numbers into variables?

I'm still new to Java, and one of the ideas I had to make things more interesting is trying to make an algorithm that would convert numbers into letters (1000 = 1k // 1.000.000 = 1M // 1E+15 = 1aa..it would be an optimizer for a mobile game) , but turn out even double type variables has a pretty small limit compared to the numbers I want to work with (i.e 9.48E+3048).
Any ideas on how to approach this issue?
import java.math.BigInteger;
...
BigInteger myint = new BigInteger("5");
myint = myint.add(new BigInteger("7")); // 12
BigIntegers are immutable (They can't change), so the process is simply to .add, .multiply, etc, to get new numbers, and then overwrite variables as shown above. They will hold arbitrarily large numbers. All other functionality can be found here.
You will want to avoid converting integer to string as it will be too slow for numbers that large. Make a custom method to convert the most significant binary digits into the strings you desire (1k, 1M, 1aa, etc).
An alternative is hold two doubles in a (mantissa, exp) format, just as double does internally. After every operation, move the mantissa's exponent into the exponent variable with exp = this.getExponent(), mantissa = this.getMantissa(). getExponent could return something like floor(log(mantissa)) + exp, and getMantissa could return mantissa / nextLowerPowerOfTen(mantissa). This will give you 10^(10^3048), with 15 digits accuracy in the mantissa and 15 digits accuracy in the exponent.

Fastest way to generate a random double number in java

In a project in which I'm working for, I'm required to either generate n random double numbers (depending from what the input file says) or converting them to doubles if I have them from my input file. Those numbers should have only 2 decimals after the comma (ex.: 0.98).
I know that in Java 8, there are 2 ways of doing this:
Java 8 way: nthNumber = Double.parseDouble(new DecimalFormat("#.##").format(ThreadLocalRandom.current().nextDouble(0,1)).replace(",","."));
Old fashion way: nthNumber = Double.parseDouble(new DecimalFormat("#.##").format(new Random().nextDouble()).replace(",", "."));
Asymptotically speaking, which is the fastest? From my poor knowledge of A.D.S., I'd say it would be the same time (O(n)?) but I'm not 100% sure
Aside from these two ways, are there any other ways to generate random doubles between 0 and 1 which are faster, asymptotically speaking, than my proposals? (rather, are there methods that can do everything in O(n) or O(1) ?)
Thank you in advance to everyone who will spend a minute to answer to this question of mine
Both of your approaches use strings as an intermediate representation, this will be quite inefficient (memory allocation, string parsing, string formatting are all relatively slow operations. You probably also want to avoid allocating multiple instances of Random.
Given that you only want two decimal digits, why not create an integer in the range of 0..99 and divide it by 100.0?
Random random = new Random(); // Only one instance needed.
for (int n = 0; n < total; n++) {
double nthRandomNumber = random.nextInt(100) / 100.0;
}
Your code looks complicated.
Did you consider the following:
DecimalFormat decimalFormat = new DecimalFormat("0.00");
String twoDigitRandom = decimalFormat.format(Math.random());
Reference:
https://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#random()
Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0.
Edit: Added after the comment:
If you would like to control the number of digits and not to have a String as end result, then I would advise not to use Double, try BigDecimal instead:
MathContext m = new MathContext(3);
BigDecimal randomWithTwoDigits = new BigDecimal(Math.random(), m);

Format decimal values with String in Java

I am new to android and java programming, so please forgive me if this is an easy question. My problem is to add % in end of the decimal value. I will get double value and don't know how much digits after decimal point, i need to convert to two digits after decimal point and finally need to add % at last position. The problem is, I will format the double value only once. I have tried like this DecimalFormat ("#.##%"), but decimal points moved two digits forward. Please help me to get out of this problem.
Using DecimalFormat ("#.##%"),
Actual : 34.142545
Output : 3414.25%
If you use % in format, it means that you want to convert value to percentage, but you need to remember that value 1 in percentage world is equal to 100% so value you use will be automatically multiplied by 100. To avoid this behaviour you can change % into literal by quoting it with apostrophes '%'
new DecimalFormat("#.##'%'");
By adding the % in the format, you multiply by 100 and add the % character. This is why it looks like the decimal point moves.
You can use something like:
String output = new DecimalFormat("#.##").format(input) + "%";
An alternative is to divide by 100 before formatting:
String output = new DecimalFormat("#.##%").format(input / 100.0);

How to print a large number with exponential notation?

If I have a number 52000000000, and I want to print it out as 5.2E+9, how do I do that with printf?
Since it's a simple method I'll guide you through it.
You'll need two counters: one for the number itself (type double, let's call it 'num'), and one for the exponent (integer, let's call it exp). You'll need a while loop such that while num is greater than 10, divide num by 10 and increase exp by 1. So, something like 7600 should have num = 7.6, exp = 3.
Depending on your return type, you can return these values in numerous ways. A simple way would be to have return type string and return num+"E"+exp.
This can be done with printf("%.2g", 52000000000);
"g" is the conversion character for scientific notation for formatting, and ".2" specifies the precision.
You need to have a look at this : DecimalFormat
formatter = new DecimalFormat("0.#E0");
System.out.println(formatter.format(value));//value is where you store the number to be formatted

How do I round up currency values in Java?

Okay, here's my problem.
Basically I have this problem.
I have a number like .53999999.
How do I round it up to 54 without using any of the Math functions?
I'm guessing I have to multiply by 100 to scale it, then divide?
Something like that?
The issue is with money. let's say I have $50.5399999 I know how to get the $50, but I don't have how to get the cents. I can get the .539999 part, but I don't know how to get it to 54 cents.
I would use something like:
BigDecimal result = new BigDecimal("50.5399999").setScale(2, BigDecimal.ROUND_HALF_UP);
There is a great article called Make cents with BigDecimal on JavaWorld that you should take a look at.
You should use a decimal or currency type to represent money, not floating point.
Math with money is more complex than most engineers think (over generalization)
If you are doing currency calculations, I think you may be delving into problems that seem simple at their surface but are actually quite complex. For instance, rounding methods that are a result of business logic decisions that are repeated often can drastically affect the totals of calculations.
I would recommend looking at the Java Currency class for currency formatting.
Also having a look at this page on representing money in java may be helpful.
If this is homework, showing the teacher that you have thought through the real-world problem rather than just slung a bunch of code together that "works" - will surely be more impressive.
On a side note, I initially was going to suggest looking at the implementation of the Java math methods in the source code, so I took a look. I noticed that Java was using native methods for its rounding methods - just like it should.
However, a look at BigDecimal shows that there is Java source available for rounding in Java. So rather than just give you the code for your homework, I suggest that you look at the BigDecimal private method doRound(MathContext mc) in the Java source.
If 50.54 isn't representable in double precision, then rounding won't help.
If you're trying to convert 50.53999999 to a whole number of dollars and a whole number of cents, do the following:
double d = 50.539999; // or however many 9's, it doesn't matter
int dollars = (int)d;
double frac = d - dollars;
int cents = (int)((frac * 100) + 0.5);
Note that the addition of 0.5 in that last step is to round to the nearest whole number of cents. If you always want it to round up, change that to add 0.9999999 instead of 0.5.
Why would you not want to use any Math functions?
static long round(double a)
-Returns the closest long to the argument.
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Math.html
To represent money I would take the following advice instead of re-inventing the wheel:
http://www.javapractices.com/topic/TopicAction.do?Id=13
Try storing your currency as number of cents (you could abstract this to number of base curreny units) with a long.
Edit: Since this is homework, you may not have control over the types. Consider this a lesson for future projects
long money = 5054;
long cents = money % 100;
long dollars = money / 100; // this works due to integer/long truncation
System.out.printf("$%d.%02.d", dollars, cents);
You need to make the number .535 and compare that with your original number to see if you'll round up or down. Here's how you get .535 from .53999999 (should work for any number):
num = .53999999;
int_num = (int)(num * 100); // cast to integer, however you do it in Java
compare_num = (int_num + 0.5) / 100;
compare_num would be .535 in this case. If num is greater than or equal to compare_num, round up to int_num + 1. Otherwise round down simply to int_num.
Sean seems to have it, except, if you want to impose proper rules then you may want to throw in an if statement like so:
double value = .539999;
int result = (int) (value*100);
if(((value*100)%result)>.5)
result++;
I suggest you use long for rounding a double value. It won't matter for small numbers but could make a difference.
double d = 50.539999;
long cents = (long)(d * 100 + 0.5);
double rounded = cents/100;
What exactly are you trying to do? Are you always trying to go to two digits? Or are you always trying to fix things like 99999 at the end no matter what?
According to the comments, it is in fact the former: rounding to dollars and cents. So indeed just round(100*a)/100 is what you want. (The latter would be much more complicated...)
Finally, if you just want to extract the cents part, the following would work:
dollars_and_cents = round(100*a)/100
cents = (dollars_and_cents-(int)dollars_and_cents)*100
(or does java just have frac? In which case the last line would just be frac(dollars_and_cents)*100.

Categories