DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Data Engineering
  3. Data
  4. String Representation of Java Decimals Without Scientific Notation

String Representation of Java Decimals Without Scientific Notation

Let's take a look at how to print out a Java decimal number in full as a string, without needing to display it in scientific notation.

Dustin Marx user avatar by
Dustin Marx
·
Nov. 21, 17 · Tutorial
Like (5)
Save
Tweet
Share
64.26K Views

Join the DZone community and get the full member experience.

Join For Free

The primary types/objects used for decimal numbers in Java are float/Float, double/Double, and BigDecimal. Each of these has cases in which its "default" string representation is "computerized scientific notation." This post demonstrates some simple approaches to provide a string representation of the decimal number in these cases without scientific notation.

Examples in this post will demonstrate the "default" exponential String representations of these Java numeric types using a range of numbers for each type that demonstrates approximately where the "default" representation for each type becomes scientific notation. The next three code listings show the code for constructing general ranges for floats, doubles, and BigDecimals.

Constructing the Example Range of Floats

/** 
 * Writes floats in the provided format and in the 
 * provided range to standard output. 
 * 
 * @param start Float to start writing. 
 * @param threshold Float past which to not write anymore. 
 * @param delta Delta for each increment of floats to be written. 
 * @param label Label for header. 
 * @param format Format for print out. 
 */
private static void writeFloatsToOutput(
    final float start,
    final float threshold,
    final float delta,
    final String label,
    final Format format) {
    out.println(generateHeader(label));
    float floatValue = start;
    do {
        out.println("= " + format.fromFloat(floatValue));
        floatValue += delta;
    }
    while (floatValue < threshold);
}


Constructing the Example Range of Doubles

/** 
 * Writes doubles in the provided format and in the 
 * provided range to standard output. 
 * 
 * @param start Double to start writing. 
 * @param threshold Double past which to not write anymore. 
 * @param delta Delta for each increment of doubles to be written. 
 * @param label Label for header. 
 * @param format Format for print out. 
 */
private static void writeDoublesToOutput(
    final double start,
    final double threshold,
    final double delta,
    final String label,
    final Format format) {
    out.println(generateHeader(label));
    double doubleValue = start;
    do {
        out.println("= " + format.fromDouble(doubleValue));
        doubleValue += delta;
    }
    while (doubleValue < threshold);
}


Constructing the Example Range of BigDecimals

/** 
 * Writes BigDecimals in the provided format and in the 
 * provided range to standard output. 
 * 
 * @param start BigDecimal to start writing. 
 * @param threshold BigDecimal past which to not write anymore. 
 * @param delta Delta for each increment of BigDecimals to be written. 
 * @param label Label for header. 
 * @param format Format for print out. 
 */
private static void writeBigDecimalsToOutput(
    final BigDecimal start,
    final BigDecimal threshold,
    final BigDecimal delta,
    final String label,
    final Format format) {
    out.println(generateHeader(label));
    BigDecimal decimal = start;
    do {
        out.println("= " + format.fromBigDecimal(decimal));
        decimal = decimal.add(delta);
    }
    while (decimal.compareTo(threshold) < 0);
}


The three methods shown above can be called with ranges specified to demonstrate when scientific notation is automatically employed for String representations of the Java decimal types. The output from running the above with "default" format for each numeric type is shown in the next three output listings.

The default representation of very small and very large floats does include scientific notation for the smallest numbers shown and for the largest numbers shown. These numbers demonstrate what is discussed in the Float.toString(Float) documentation: numbers "less than 10-3 or greater than or equal to 107" are "represented in so-called 'computerized scientific notation.'"

==========================
= Small Floats (DEFAULT) =
==========================
= 8.5E-4
= 9.5E-4
= 0.00105
= 0.0011499999
= 0.0012499999
= 0.0013499998
= 0.0014499997
= 0.0015499997
= 0.0016499996
= 0.0017499996
= 0.0018499995
= 0.0019499995
==========================
= Large Floats (DEFAULT) =
==========================
= 9999995.0
= 9999996.0
= 9999997.0
= 9999998.0
= 9999999.0
= 1.0E7
= 1.0000001E7
= 1.0000002E7
= 1.0000003E7
= 1.0000004E7


The default representation of very small and very large doubles does include scientific notation for the smallest numbers shown and for the largest numbers shown. These numbers demonstrate what is discussed in the Javadoc documentation for Double.toString(double): numbers "less than 10-3 or greater than or equal to 107" are "represented in so-called 'computerized scientific notation.'"

===========================
= Small Doubles (DEFAULT) =
===========================
= 8.5E-4
= 9.5E-4
= 0.00105
= 0.00115
= 0.00125
= 0.00135
= 0.0014500000000000001
= 0.0015500000000000002
= 0.0016500000000000002
= 0.0017500000000000003
= 0.0018500000000000003
= 0.0019500000000000003
===========================
= Large Doubles (DEFAULT) =
===========================
= 9999995.0
= 9999996.0
= 9999997.0
= 9999998.0
= 9999999.0
= 1.0E7
= 1.0000001E7
= 1.0000002E7
= 1.0000003E7
= 1.0000004E7


While float and double had their smallest and largest numbers expressed in scientific notation, BigDecimal only does this by default for smaller numbers. This is described in the BigDecimal.toString() Javadoc documentation: "If the scale is greater than or equal to zero and the adjusted exponent is greater than or equal to -6, the number will be converted to a character form without using exponential notation. ... if ... the adjusted exponent is less than -6, the number will be converted to a character form using exponential notation."

===============================
= Small BigDecimals (DEFAULT) =
===============================
= 8.5E-7
= 9.5E-7
= 0.00000105
= 0.00000115
= 0.00000125
= 0.00000135
= 0.00000145
= 0.00000155
= 0.00000165
= 0.00000175
= 0.00000185
= 0.00000195
===============================
= Large BigDecimals (DEFAULT) =
===============================
= 99999950000000000000000000000000000000000000000000
= 99999960000000000000000000000000000000000000000000
= 99999970000000000000000000000000000000000000000000
= 99999980000000000000000000000000000000000000000000
= 99999990000000000000000000000000000000000000000000
= 100000000000000000000000000000000000000000000000000
= 100000010000000000000000000000000000000000000000000
= 100000020000000000000000000000000000000000000000000
= 100000030000000000000000000000000000000000000000000
= 100000040000000000000000000000000000000000000000000


private static void writeFormattedValues(final Format format) {
    writeFloatsToOutput(
        0.00085 f, 0.002 f, 0.0001 f, "Small Floats (" + format + ")", format);
    writeFloatsToOutput(
        9 _999_995f, 10 _000_005f, 1 f, "Large Floats (" + format + ")", format);

    writeDoublesToOutput(
        0.00085 d, 0.002 d, 0.0001 d, "Small Doubles (" + format + ")", format);
    writeDoublesToOutput(
        9 _999_995d, 10 _000_005d, 1 d, "Large Doubles (" + format + ")", format);

    writeBigDecimalsToOutput(
        new BigDecimal("0.00000085"),
        new BigDecimal("0.000002"),
        new BigDecimal("0.0000001"),
        "Small BigDecimals (" + format + ")",
        format);
    writeBigDecimalsToOutput(
        new BigDecimal("99999950000000000000000000000000000000000000000000"),
        new BigDecimal("100000050000000000000000000000000000000000000000000"),
        new BigDecimal("10000000000000000000000000000000000000000000"),
        "Large BigDecimals (" + format + ")",
        format);
}


The representation of very small and very large numbers in the code above can be presented in default format or in a format the precludes use of scientific notation. The code listing for the Format enum is shown next and this enum demonstrates approaches that can be used with float, double, and BigDecimal to render them without scientific notation.

Format.java:

/** 
 * Supports rendering of Java numeric types float, double, 
 * and BigDecimal in "default" format and in format that 
 * avoids use of scientific notation. 
 */
public enum Format {
    DEFAULT {
        @Override
        public String fromFloat(final float floatValue) {
            return String.valueOf(floatValue);
        }
        @Override
        public String fromDouble(final double doubleValue) {
            return String.valueOf(doubleValue);
        }
        @Override
        public String fromBigDecimal(final BigDecimal bigDecimalValue) {
            return bigDecimalValue.toString();
        }
    },
    NO_EXPONENT {
        @Override
        public String fromFloat(final float floatValue) {
            return numberFormat.format(floatValue);
        }
        @Override
        public String fromDouble(final double doubleValue) {
            return numberFormat.format(doubleValue);
        }
        @Override
        public String fromBigDecimal(final BigDecimal bigDecimalValue) {
            return bigDecimalValue.toPlainString();
        }
    };

    private static final NumberFormat numberFormat = NumberFormat.getInstance();

    static {
        numberFormat.setMaximumFractionDigits(Integer.MAX_VALUE);
        numberFormat.setGroupingUsed(false);
    }

    public abstract String fromFloat(final float floatValue);
    public abstract String fromDouble(final double doubleValue);
    public abstract String fromBigDecimal(final BigDecimal bigDecimalValue);
}


The Format enum uses an instance of NumberFormat with grouping disabled and with the maximum fraction digits set to Integer.MAX_VALUE to ensure that floats and doubles are rendered without scientific notation. It's even easier to accomplish this with BigDecimal using its toPlainString() method.

The output from running the code with the Format.NO_EXPONENT is shown next (and there's no exponents or scientific notation in sight).

==============================
= Small Floats (NO_EXPONENT) =
==============================
= 0.0008500000112690032
= 0.0009500000160187483
= 0.0010499999625608325
= 0.0011499999091029167
= 0.001249999855645001
= 0.0013499998021870852
= 0.0014499997487291694
= 0.0015499996952712536
= 0.0016499996418133378
= 0.001749999588355422
= 0.0018499995348975062
= 0.0019499994814395905
==============================
= Large Floats (NO_EXPONENT) =
==============================
= 9999995
= 9999996
= 9999997
= 9999998
= 9999999
= 10000000
= 10000001
= 10000002
= 10000003
= 10000004
===============================
= Small Doubles (NO_EXPONENT) =
===============================
= 0.00085
= 0.00095
= 0.00105
= 0.00115
= 0.00125
= 0.00135
= 0.0014500000000000001
= 0.0015500000000000002
= 0.0016500000000000002
= 0.0017500000000000003
= 0.0018500000000000003
= 0.0019500000000000003
===============================
= Large Doubles (NO_EXPONENT) =
===============================
= 9999995
= 9999996
= 9999997
= 9999998
= 9999999
= 10000000
= 10000001
= 10000002
= 10000003
= 10000004
===================================
= Small BigDecimals (NO_EXPONENT) =
===================================
= 0.00000085
= 0.00000095
= 0.00000105
= 0.00000115
= 0.00000125
= 0.00000135
= 0.00000145
= 0.00000155
= 0.00000165
= 0.00000175
= 0.00000185
= 0.00000195
===================================
= Large BigDecimals (NO_EXPONENT) =
===================================
= 99999950000000000000000000000000000000000000000000
= 99999960000000000000000000000000000000000000000000
= 99999970000000000000000000000000000000000000000000
= 99999980000000000000000000000000000000000000000000
= 99999990000000000000000000000000000000000000000000
= 100000000000000000000000000000000000000000000000000
= 100000010000000000000000000000000000000000000000000
= 100000020000000000000000000000000000000000000000000
= 100000030000000000000000000000000000000000000000000
= 100000040000000000000000000000000000000000000000000


The standard Java floating types and BigDecimal class render some numbers in scientific notation, but it's easy to ensure that this default presentation of scientific notation is not used when it is not desired.

Java (programming language) Strings Data Types

Published at DZone with permission of Dustin Marx, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • SAST: How Code Analysis Tools Look for Security Flaws
  • A Simple Union Between .NET Core and Python
  • Data Mesh vs. Data Fabric: A Tale of Two New Data Paradigms
  • The Top 3 Challenges Facing Engineering Leaders Today—And How to Overcome Them

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: