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
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

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

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • The Long Road to Java Virtual Threads
  • Exploring Exciting New Features in Java 17 With Examples
  • Proper Java Exception Handling
  • Generics in Java and Their Implementation

Trending

  • The Cypress Edge: Next-Level Testing Strategies for React Developers
  • How AI Agents Are Transforming Enterprise Automation Architecture
  • AI’s Role in Everyday Development
  • Article Moderation: Your Questions, Answered
  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.

By 
Dustin Marx user avatar
Dustin Marx
·
Nov. 21, 17 · Tutorial
Likes (5)
Comment
Save
Tweet
Share
71.4K 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.

Related

  • The Long Road to Java Virtual Threads
  • Exploring Exciting New Features in Java 17 With Examples
  • Proper Java Exception Handling
  • Generics in Java and Their Implementation

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

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

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!