Return-Path: X-Original-To: apmail-commons-issues-archive@minotaur.apache.org Delivered-To: apmail-commons-issues-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 99DDB11654 for ; Fri, 12 Sep 2014 12:38:34 +0000 (UTC) Received: (qmail 26368 invoked by uid 500); 12 Sep 2014 12:38:34 -0000 Delivered-To: apmail-commons-issues-archive@commons.apache.org Received: (qmail 26260 invoked by uid 500); 12 Sep 2014 12:38:34 -0000 Mailing-List: contact issues-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: issues@commons.apache.org Delivered-To: mailing list issues@commons.apache.org Received: (qmail 26247 invoked by uid 99); 12 Sep 2014 12:38:34 -0000 Received: from arcas.apache.org (HELO arcas.apache.org) (140.211.11.28) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 12 Sep 2014 12:38:34 +0000 Date: Fri, 12 Sep 2014 12:38:34 +0000 (UTC) From: "Duncan Jones (JIRA)" To: issues@commons.apache.org Message-ID: In-Reply-To: References: Subject: [jira] [Comment Edited] (LANG-1018) NumberUtils.createNumber(final String str) Precision will be lost MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 [ https://issues.apache.org/jira/browse/LANG-1018?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14131473#comment-14131473 ] Duncan Jones edited comment on LANG-1018 at 9/12/14 12:38 PM: -------------------------------------------------------------- Closely related discussion found at LANG-693. The problem is that [Java allocates 23-bits|http://stackoverflow.com/a/13543600/474189] for the [significand|http://en.wikipedia.org/wiki/Significand] in a float. This guarantees *6* decimal figures in the significand, not 7. The fix for LANG-693 checks for the wrong values. I need to do some more investigation, but I see two solutions: # Leave the simple test in place, but change to {{< 7}} and {{< 16}} for floats and doubles respectively. And change it to count the size of the significand, not just the decimal places. # Change the approach and calculate the bit-length of the significand and switch types based on that. was (Author: dmjones500): Closely related discussion found at LANG-693. The problem is that [Java allocates 23-bits|http://stackoverflow.com/a/13543600/474189] for the [significand|http://en.wikipedia.org/wiki/Significand] in a float. This guarantees *6* decimal figures in the significand, not 7. The fix for LANG-693 checks for the wrong values. I need to do some more investigation, but I see two solutions: # Leave the simple test in place, but change to {{< 7}} and {{< 16}} for floats and doubles respectively. # Change the approach and calculate the bit-length of the significand and switch types based on that. > NumberUtils.createNumber(final String str) Precision will be lost > ------------------------------------------------------------------ > > Key: LANG-1018 > URL: https://issues.apache.org/jira/browse/LANG-1018 > Project: Commons Lang > Issue Type: Bug > Components: lang.math.* > Affects Versions: 3.3.2 > Environment: windows 7 > Reporter: sydng > Fix For: Patch Needed > > > With commons-lang 3.2.2: > NumberUtils.createNumber("-160952.54"); > The result is "-160952.55". > Should not be based on the length of the decimal point number to judge whether the floating point number. > Using the method (createFloat(str)) of dealing with the valid number greater than seven Numbers will cause accuracy loss. > The source code is as follows: > {code:java} > try { > if(numDecimals <= 7){// If number has 7 or fewer digits past the decimal point then make it a float > final Float f = createFloat(str); > if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) { > return f; > } > } > } catch (final NumberFormatException nfe) { // NOPMD > // ignore the bad number > } > try { > if(numDecimals <= 16){// If number has between 8 and 16 digits past the decimal point then make it a double > final Double d = createDouble(str); > if (!(d.isInfinite() || (d.doubleValue() == 0.0D && !allZeros))) { > return d; > } > } > } catch (final NumberFormatException nfe) { // NOPMD > // ignore the bad number > } > return createBigDecimal(str); > } > {code} -- This message was sent by Atlassian JIRA (v6.3.4#6332)