Displaying doubles to a certain precision in java - java

I am currently writing a calculator application. I know that a double is not the best choice for good math. Most of the functions in the application have great precision but the ones that don't get super ugly results. My solution is to show users only 12 decimals of precision. I chose 12 because my lowest precision comes from my numerical derive function.
The issue I am having is that if I multiply it by a scaler then round then divide by the scaler the precision will most likely be thrown out of whack. If I use DecimalFormat there is no way to show only 12 and have the E for scientific notation show up correctly, but not be there if it doesn’t need to be.
for example I want
1.23456789111213 to be 1.234567891112
but never
1.234567891112E0
but I also want
1.23456789111213E23 to be 1.234567891112E23
So basically I want to format the string of a number to 12 decimals places, preserving scientific notation, but not being scientific when it shouldn't

Use String.format("%.12G", doubleVariable);
That is how you use format() to display values in scientific notation, but without the scientific notation if not needed. The one caveat is that you end up with a '+' after the 'E', so yours would end up like 1.234567891112E+23

String.format("%.12d", doubleVariable);
Should give you what you are looking for in your first matter. I'm sorry but I don't know how to define when your E-notification is showed.

You'll be interested in BigDecimal, for example:
BigDecimal number = new BigDecimal("1.23456789111213");
number = number.setScale(12, RoundingMode.HALF_UP);
System.out.println(number);
Choose appropriate to you RoundingMode.

Related

Wrong Decimal Converting from Double to String in java

I have A String that is formatted correctly to be cast to a double and it works fine for most decimals. The issue is that for .33, .67, and possibly others I haven't tested, the decimal becomes something like .6700000000002, or .329999999998. I understand why this happens but does any one have a suggestion to fix it.
It's a result of IEEE-754 rounding rules, some numbers cannot be represented precisely in two's complement. For example, 1/10 is not precisely representable.
You can add more precision (but not infinite) by using BigDecimal.
BigDecimal oneTenth = new BigDecimal("1").divide(new BigDecimal("10"));
System.out.println(oneTenth);
Which outputs 0.1
Some decimal numbers can not be represented accurately with the internal base 2 machine representation.
That's double precision for you. Binary numbers and decimals don't work well together. Unless you are doing something really precise it should be fine, if you are printing it you should use either decimal format or printf.
Value of floating point numbers are not stored directly but with exponential values. You may write 3.1233453456356 as number, but this is stored something like 3 and 2^6 in memory. It tries to store a value as close as your number, but those differences can happen.
It shouldn't be a problem unless you're testing for equality. With floating-point tests for equality you'll need to allow a "delta" so that:
if (a == b)
becomes
if (abs(a-b) < 0.000001)
or a similar small delta value. For printing, limit it to two decimal places and the formatter will round it for you.

Unify 10^x power in a sequence of number

I have a sequence of numbers like this:
1.687155E21
3.981457E19
0.5532155E21
3.018843E21
2.0532155E21
4.5532155E21
3.1637913E19
My problem is how to convert the two numbers which ends with 10^19 to be like the others (10^21). Because after this unification i need to trunc the number to print only something like 3.5.
In C/C++ i know how to work with precision, but in Java I haven't got any idea.
Divide all your number by / 1e19, round to as many decimal digits you want:
168.7155
3.981457
55.32155
301.8843
205.32155
455.32155
3.1637913
Use the Formatter Class to bring them into the desired scientific notation (java.util.Formatter)
I'd suggest something similar as Tomasz Nurkiewicz did, but instead of dividing by 1E19 divide by 1E21, convert them to strings with the required precision using Formatter (see the comment of count0) but not as scientific format, but as a general one. In the end just add E21 to those strings. In the end you should get (I hope, I got the idea correctly)
1.687155E21
0.03981457E21
0.5532155E21
3.018843E21
2.0532155E21
4.5532155E21
0.031637913E21
Can't you just multiply the E19 numbers by 10 ^ 2 = 100?
After they have been normalized to E21, you should be able to divide all of them by 10^21 (if they're floats), and they will all be in the range of 0-9.999...

scientific notation abstraction in java

Is there a java class abstraction to denote scientific numbers (e.g. the number, 10 power modulus), so that I can do simple operations like multiplication or division on top of them.
Note: Looking for something similar to Fraction here.
As Emil said, BigDecimal helps you. It doesn't have a constructor that lets you enter a double mantissa and an int exponent. You could extend the class to make a new constructor, or, you could define a DecimalFormat. I think that the class DecimalFormat will do some of what you want. It allows you how to define how a number 'looks'. You need to define the format using a String, the tutorial is
http://download.oracle.com/javase/tutorial/i18n/format/decimalFormat.html
You would have to define the format of scientific numbers, call yourDecimalFormat.parse(yourStringtoBecomeScientificNumber) which will give you a Number, then cast it as a BigDecimal to do arithmetic on it.
Also note that this should allow you to force a certain number of significant figures or digits to left of decimal point.
I didn't get your example.If you need a different type of number representation then you can do so by extending abstract class Number.Also have a look at BigDecimals .I think this is what you are looking for.
You could write the number as number+e+exponent, e.g.:
1e2 instead of 100.
Multiplication and Division should work for it.

How to do intelligent decimal cut off in Java?

I want to implement or use some library for an intelligent decimal cut off.
I mean that I would like to get: from 3.456432 -> 3.4, from 0.0000023232432 -> 0.000002 and from 0.000000000001 -> 0.0 (or something like that). I need this feature for a convinient user GUI.
Thereby I need to reduce number of digits that are not equal to zero. I need to keep 1-3 most significant digits and other set to zero.
Have you taken a look at the DecimalFormat API?
DecimalFormat is a concrete subclass
of NumberFormat that formats decimal
numbers. It has a variety of features
designed to make it possible to parse
and format numbers in any locale,
including support for Western, Arabic,
and Indic digits. It also supports
different kinds of numbers, including
integers (123), fixed-point numbers
(123.4), scientific notation (1.23E4),
percentages (12%), and currency
amounts ($123). All of these can be
localized.
If it is of any help, you can use the following method to round a double to a specified number of significant digits. There are however no functionality in the standard API to output the result in a reasonable manner:
private static double round(double v, int sigDigits) {
double f = Math.pow(10, Math.ceil(Math.log10(Math.abs(v))) - sigDigits);
return Math.round(v/f)*f;
}
Since Java 5, java.util has a Formatter class which can do what you need.

How do I convert a double to a fraction in a format suitable for representing inches?

I am using the Apache Commons math.Fraction class to convert my doubles to fractions, which is working fine.
However, I need it to calculate these fractions in a way that makes sense for displaying lengths in inches, to the nearest 1/32".
For example, converting 0.325 to a fraction yields 12/37, which doesn't make sense to someone looking at a US ruler. I suppose I want to round the decimal to the nearest .03125 before i convert it, if that makes sense. My basic math skills are failing me :(
edit
To clarify, all the input is in decimal inches between 0 and 1. Given the sample input above, I would want 5/16".
can you multiply the fractional part by 32 then round?

Categories