Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
159985af
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
159985af
编写于
1月 11, 2013
作者:
D
darcy
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
7131459: [Fmt-De] DecimalFormat produces wrong format() results when close to a tie
Reviewed-by: darcy Contributed-by: olivier.lagneau@oracle.com
上级
bf1f39d1
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
568 addition
and
17 deletion
+568
-17
src/share/classes/java/text/DigitList.java
src/share/classes/java/text/DigitList.java
+128
-15
src/share/classes/sun/misc/FloatingDecimal.java
src/share/classes/sun/misc/FloatingDecimal.java
+29
-2
test/java/text/Format/DecimalFormat/TieRoundingTest.java
test/java/text/Format/DecimalFormat/TieRoundingTest.java
+411
-0
未找到文件。
src/share/classes/java/text/DigitList.java
浏览文件 @
159985af
/*
* Copyright (c) 1996, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -41,6 +41,7 @@ package java.text;
import
java.math.BigDecimal
;
import
java.math.BigInteger
;
import
java.math.RoundingMode
;
import
sun.misc.FloatingDecimal
;
/**
* Digit List. Private to DecimalFormat.
...
...
@@ -62,7 +63,7 @@ import java.math.RoundingMode;
* derived by placing all the digits of the list to the right of the
* decimal point, by 10^exponent.
*
* @see
java.util.
Locale
* @see Locale
* @see Format
* @see NumberFormat
* @see DecimalFormat
...
...
@@ -286,14 +287,27 @@ final class DigitList implements Cloneable {
* fractional digits to be converted. If false, total digits.
*/
final
void
set
(
boolean
isNegative
,
double
source
,
int
maximumDigits
,
boolean
fixedPoint
)
{
set
(
isNegative
,
Double
.
toString
(
source
),
maximumDigits
,
fixedPoint
);
FloatingDecimal
fd
=
new
FloatingDecimal
(
source
);
boolean
hasBeenRoundedUp
=
fd
.
digitsRoundedUp
();
boolean
allDecimalDigits
=
fd
.
decimalDigitsExact
();
String
digitsString
=
fd
.
toJavaFormatString
();
set
(
isNegative
,
digitsString
,
hasBeenRoundedUp
,
allDecimalDigits
,
maximumDigits
,
fixedPoint
);
}
/**
* Generate a representation of the form DDDDD, DDDDD.DDDDD, or
* DDDDDE+/-DDDDD.
* @param roundedUp Boolean value indicating if the s digits were rounded-up.
* @param allDecimalDigits Boolean value indicating if the digits in s are
* an exact decimal representation of the double that was passed.
*/
final
void
set
(
boolean
isNegative
,
String
s
,
int
maximumDigits
,
boolean
fixedPoint
)
{
final
void
set
(
boolean
isNegative
,
String
s
,
boolean
roundedUp
,
boolean
allDecimalDigits
,
int
maximumDigits
,
boolean
fixedPoint
)
{
this
.
isNegative
=
isNegative
;
int
len
=
s
.
length
();
char
[]
source
=
getDataChars
(
len
);
...
...
@@ -346,7 +360,7 @@ final class DigitList implements Cloneable {
}
else
if
(-
decimalAt
==
maximumDigits
)
{
// If we round 0.0009 to 3 fractional digits, then we have to
// create a new one digit in the least significant location.
if
(
shouldRoundUp
(
0
))
{
if
(
shouldRoundUp
(
0
,
roundedUp
,
allDecimalDigits
))
{
count
=
1
;
++
decimalAt
;
digits
[
0
]
=
'1'
;
...
...
@@ -365,19 +379,26 @@ final class DigitList implements Cloneable {
// Eliminate digits beyond maximum digits to be displayed.
// Round up if appropriate.
round
(
fixedPoint
?
(
maximumDigits
+
decimalAt
)
:
maximumDigits
);
round
(
fixedPoint
?
(
maximumDigits
+
decimalAt
)
:
maximumDigits
,
roundedUp
,
allDecimalDigits
);
}
/**
* Round the representation to the given number of digits.
* @param maximumDigits The maximum number of digits to be shown.
* @param alreadyRounded Boolean indicating if rounding up already happened.
* @param allDecimalDigits Boolean indicating if the digits provide an exact
* representation of the value.
*
* Upon return, count will be less than or equal to maximumDigits.
*/
private
final
void
round
(
int
maximumDigits
)
{
private
final
void
round
(
int
maximumDigits
,
boolean
alreadyRounded
,
boolean
allDecimalDigits
)
{
// Eliminate digits beyond maximum digits to be displayed.
// Round up if appropriate.
if
(
maximumDigits
>=
0
&&
maximumDigits
<
count
)
{
if
(
shouldRoundUp
(
maximumDigits
))
{
if
(
shouldRoundUp
(
maximumDigits
,
alreadyRounded
,
allDecimalDigits
))
{
// Rounding up involved incrementing digits from LSD to MSD.
// In most cases this is simple, but in a worst case situation
// (9999..99) we have to adjust the decimalAt value.
...
...
@@ -423,8 +444,56 @@ final class DigitList implements Cloneable {
* @return true if digit <code>maximumDigits-1</code> should be
* incremented
*/
private
boolean
shouldRoundUp
(
int
maximumDigits
)
{
private
boolean
shouldRoundUp
(
int
maximumDigits
,
boolean
alreadyRounded
,
boolean
allDecimalDigits
)
{
if
(
maximumDigits
<
count
)
{
/*
* To avoid erroneous double-rounding or truncation when converting
* a binary double value to text, information about the exactness
* of the conversion result in FloatingDecimal, as well as any
* rounding done, is needed in this class.
*
* - For the HALF_DOWN, HALF_EVEN, HALF_UP rounding rules below:
* In the case of formating float or double, We must take into
* account what FloatingDecimal has done in the binary to decimal
* conversion.
*
* Considering the tie cases, FloatingDecimal may round-up the
* value (returning decimal digits equal to tie when it is below),
* or "truncate" the value to the tie while value is above it,
* or provide the exact decimal digits when the binary value can be
* converted exactly to its decimal representation given formating
* rules of FloatingDecimal ( we have thus an exact decimal
* representation of the binary value).
*
* - If the double binary value was converted exactly as a decimal
* value, then DigitList code must apply the expected rounding
* rule.
*
* - If FloatingDecimal already rounded up the decimal value,
* DigitList should neither round up the value again in any of
* the three rounding modes above.
*
* - If FloatingDecimal has truncated the decimal value to
* an ending '5' digit, DigitList should round up the value in
* all of the three rounding modes above.
*
*
* This has to be considered only if digit at maximumDigits index
* is exactly the last one in the set of digits, otherwise there are
* remaining digits after that position and we dont have to consider
* what FloatingDecimal did.
*
* - Other rounding modes are not impacted by these tie cases.
*
* - For other numbers that are always converted to exact digits
* (like BigInteger, Long, ...), the passed alreadyRounded boolean
* have to be set to false, and allDecimalDigits has to be set to
* true in the upper DigitList call stack, providing the right state
* for those situations..
*/
switch
(
roundingMode
)
{
case
UP:
for
(
int
i
=
maximumDigits
;
i
<
count
;
++
i
)
{
...
...
@@ -451,6 +520,13 @@ final class DigitList implements Cloneable {
break
;
case
HALF_UP:
if
(
digits
[
maximumDigits
]
>=
'5'
)
{
// We should not round up if the rounding digits position is
// exactly the last index and if digits were already rounded.
if
((
maximumDigits
==
(
count
-
1
))
&&
(
alreadyRounded
))
return
false
;
// Value was exactly at or was above tie. We must round up.
return
true
;
}
break
;
...
...
@@ -458,6 +534,21 @@ final class DigitList implements Cloneable {
if
(
digits
[
maximumDigits
]
>
'5'
)
{
return
true
;
}
else
if
(
digits
[
maximumDigits
]
==
'5'
)
{
if
(
maximumDigits
==
(
count
-
1
))
{
// The rounding position is exactly the last index.
if
(
allDecimalDigits
||
alreadyRounded
)
/* FloatingDecimal rounded up (value was below tie),
* or provided the exact list of digits (value was
* an exact tie). We should not round up, following
* the HALF_DOWN rounding rule.
*/
return
false
;
else
// Value was above the tie, we must round up.
return
true
;
}
// We must round up if it gives a non null digit after '5'.
for
(
int
i
=
maximumDigits
+
1
;
i
<
count
;
++
i
)
{
if
(
digits
[
i
]
!=
'0'
)
{
return
true
;
...
...
@@ -470,12 +561,32 @@ final class DigitList implements Cloneable {
if
(
digits
[
maximumDigits
]
>
'5'
)
{
return
true
;
}
else
if
(
digits
[
maximumDigits
]
==
'5'
)
{
for
(
int
i
=
maximumDigits
+
1
;
i
<
count
;
++
i
)
{
if
(
digits
[
i
]
!=
'0'
)
{
if
(
maximumDigits
==
(
count
-
1
))
{
// the rounding position is exactly the last index :
if
(
alreadyRounded
)
// If FloatingDecimal rounded up (value was below tie),
// then we should not round up again.
return
false
;
if
(!
allDecimalDigits
)
// Otherwise if the digits dont represent exact value,
// value was above tie and FloatingDecimal truncated
// digits to tie. We must round up.
return
true
;
else
{
// This is an exact tie value, and FloatingDecimal
// provided all of the exact digits. We thus apply
// HALF_EVEN rounding rule.
return
((
maximumDigits
>
0
)
&&
(
digits
[
maximumDigits
-
1
]
%
2
!=
0
));
}
}
else
{
// Rounds up if it gives a non null digit after '5'
for
(
int
i
=
maximumDigits
+
1
;
i
<
count
;
++
i
)
{
if
(
digits
[
i
]
!=
'0'
)
return
true
;
}
}
return
maximumDigits
>
0
&&
(
digits
[
maximumDigits
-
1
]
%
2
!=
0
);
}
break
;
case
UNNECESSARY:
...
...
@@ -542,7 +653,7 @@ final class DigitList implements Cloneable {
count
=
right
-
left
+
1
;
System
.
arraycopy
(
digits
,
left
,
digits
,
0
,
count
);
}
if
(
maximumDigits
>
0
)
round
(
maximumDigits
);
if
(
maximumDigits
>
0
)
round
(
maximumDigits
,
false
,
true
);
}
/**
...
...
@@ -559,7 +670,9 @@ final class DigitList implements Cloneable {
String
s
=
source
.
toString
();
extendDigits
(
s
.
length
());
set
(
isNegative
,
s
,
maximumDigits
,
fixedPoint
);
set
(
isNegative
,
s
,
false
,
true
,
maximumDigits
,
fixedPoint
);
}
/**
...
...
@@ -584,7 +697,7 @@ final class DigitList implements Cloneable {
count
=
right
+
1
;
if
(
maximumDigits
>
0
)
{
round
(
maximumDigits
);
round
(
maximumDigits
,
false
,
true
);
}
}
...
...
src/share/classes/sun/misc/FloatingDecimal.java
浏览文件 @
159985af
/*
* Copyright (c) 1996, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -41,6 +41,19 @@ public class FloatingDecimal{
boolean
fromHex
=
false
;
int
roundDir
=
0
;
// set by doubleValue
/*
* The fields below provides additional information about the result of
* the binary to decimal digits conversion done in dtoa() and roundup()
* methods. They are changed if needed by those two methods.
*/
// True if the dtoa() binary to decimal conversion was exact.
boolean
exactDecimalConversion
=
false
;
// True if the result of the binary to decimal conversion was rounded-up
// at the end of the conversion process, i.e. roundUp() method was called.
boolean
decimalDigitsRoundedUp
=
false
;
private
FloatingDecimal
(
boolean
negSign
,
int
decExponent
,
char
[]
digits
,
int
n
,
boolean
e
)
{
isNegative
=
negSign
;
...
...
@@ -396,6 +409,11 @@ public class FloatingDecimal{
// else fall through.
}
digits
[
i
]
=
(
char
)(
q
+
1
);
decimalDigitsRoundedUp
=
true
;
}
public
boolean
digitsRoundedUp
()
{
return
decimalDigitsRoundedUp
;
}
/*
...
...
@@ -751,6 +769,7 @@ public class FloatingDecimal{
digits
[
ndigit
++]
=
(
char
)(
'0'
+
q
);
}
lowDigitDifference
=
(
b
<<
1
)
-
tens
;
exactDecimalConversion
=
(
b
==
0
);
}
else
{
// still good! they're all longs!
long
b
=
(
fractBits
*
long5pow
[
B5
]
)
<<
B2
;
...
...
@@ -804,8 +823,10 @@ public class FloatingDecimal{
digits
[
ndigit
++]
=
(
char
)(
'0'
+
q
);
}
lowDigitDifference
=
(
b
<<
1
)
-
tens
;
exactDecimalConversion
=
(
b
==
0
);
}
}
else
{
FDBigInt
ZeroVal
=
new
FDBigInt
(
0
);
FDBigInt
tenSval
;
int
shiftBias
;
...
...
@@ -859,8 +880,10 @@ public class FloatingDecimal{
if
(
high
&&
low
){
Bval
.
lshiftMe
(
1
);
lowDigitDifference
=
Bval
.
cmp
(
tenSval
);
}
else
}
else
{
lowDigitDifference
=
0L
;
// this here only for flow analysis!
}
exactDecimalConversion
=
(
Bval
.
cmp
(
ZeroVal
)
==
0
);
}
this
.
decExponent
=
decExp
+
1
;
this
.
digits
=
digits
;
...
...
@@ -883,6 +906,10 @@ public class FloatingDecimal{
}
}
public
boolean
decimalDigitsExact
()
{
return
exactDecimalConversion
;
}
public
String
toString
(){
// most brain-dead version
...
...
test/java/text/Format/DecimalFormat/TieRoundingTest.java
0 → 100644
浏览文件 @
159985af
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
*
* @bug 7131459
* @summary test various situations of NumberFormat rounding when close to tie
* @author Olivier Lagneau
* @run main TieRoundingTest
*
*/
import
java.math.BigDecimal
;
import
java.math.BigInteger
;
import
java.text.NumberFormat
;
import
java.text.DecimalFormat
;
import
java.math.RoundingMode
;
import
java.util.Locale
;
public
class
TieRoundingTest
{
static
int
testCounter
=
0
;
static
int
errorCounter
=
0
;
static
boolean
allPassed
=
true
;
static
void
formatOutputTestDouble
(
NumberFormat
nf
,
double
doubleToTest
,
String
tiePosition
,
String
inputDigits
,
String
expectedOutput
)
{
int
mfd
=
nf
.
getMaximumFractionDigits
();
RoundingMode
rm
=
nf
.
getRoundingMode
();
String
result
=
nf
.
format
(
doubleToTest
);
if
(!
result
.
equals
(
expectedOutput
))
{
System
.
out
.
println
();
System
.
out
.
println
(
"========================================"
);
System
.
out
.
println
(
"***Error formatting double value from string : "
+
inputDigits
);
System
.
out
.
println
(
"NumberFormat pattern is : "
+
((
DecimalFormat
)
nf
).
toPattern
());
System
.
out
.
println
(
"Maximum number of fractional digits : "
+
mfd
);
System
.
out
.
println
(
"Fractional rounding digit : "
+
(
mfd
+
1
));
System
.
out
.
println
(
"Position of value relative to tie : "
+
tiePosition
);
System
.
out
.
println
(
"Rounding Mode : "
+
rm
);
System
.
out
.
println
(
"BigDecimal output : "
+
new
BigDecimal
(
doubleToTest
).
toString
());
System
.
out
.
println
(
"FloatingDecimal output : "
+
doubleToTest
);
System
.
out
.
println
(
"Error. Formatted result different from expected."
+
"\nExpected output is : \""
+
expectedOutput
+
"\""
+
"\nFormated output is : \""
+
result
+
"\""
);
System
.
out
.
println
(
"========================================"
);
System
.
out
.
println
();
errorCounter
++;
allPassed
=
false
;
}
else
{
testCounter
++;
System
.
out
.
println
(
"\nSuccess for double value : "
+
doubleToTest
+
" :"
);
System
.
out
.
println
(
" Input digits :"
+
inputDigits
+
", BigDecimal value : "
+
new
BigDecimal
(
doubleToTest
).
toString
());
System
.
out
.
print
(
" Rounding mode: "
+
rm
);
System
.
out
.
print
(
", fract digits : "
+
mfd
);
System
.
out
.
print
(
", position : "
+
tiePosition
+
" tie"
);
System
.
out
.
print
(
", result : "
+
result
);
System
.
out
.
println
(
", expected : "
+
expectedOutput
);
}
}
static
void
formatOutputTestLong
(
NumberFormat
nf
,
long
longToTest
,
String
tiePosition
,
String
inputDigits
,
String
expectedOutput
)
{
int
mfd
=
nf
.
getMaximumFractionDigits
();
RoundingMode
rm
=
nf
.
getRoundingMode
();
String
result
=
nf
.
format
(
longToTest
);
if
(!
result
.
equals
(
expectedOutput
))
{
System
.
out
.
println
();
System
.
out
.
println
(
"========================================"
);
System
.
out
.
println
(
"***Error formatting double value from string : "
+
inputDigits
);
System
.
out
.
println
(
"NumberFormat pattern is : "
+
((
DecimalFormat
)
nf
).
toPattern
());
System
.
out
.
println
(
"Maximum number of fractional digits : "
+
mfd
);
System
.
out
.
println
(
"Fractional rounding digit : "
+
(
mfd
+
1
));
System
.
out
.
println
(
"Position of value relative to tie : "
+
tiePosition
);
System
.
out
.
println
(
"Rounding Mode : "
+
rm
);
System
.
out
.
println
(
"Error. Formatted result different from expected."
+
"\nExpected output is : \""
+
expectedOutput
+
"\""
+
"\nFormated output is : \""
+
result
+
"\""
);
System
.
out
.
println
(
"========================================"
);
System
.
out
.
println
();
errorCounter
++;
allPassed
=
false
;
}
else
{
testCounter
++;
System
.
out
.
print
(
"Success. Long input :"
+
inputDigits
);
System
.
out
.
print
(
", rounding : "
+
rm
);
System
.
out
.
print
(
", fract digits : "
+
mfd
);
System
.
out
.
print
(
", tie position : "
+
tiePosition
);
System
.
out
.
println
(
", expected : "
+
expectedOutput
);
}
}
static
void
formatOutputTestObject
(
NumberFormat
nf
,
Object
someNumber
,
String
tiePosition
,
String
inputDigits
,
String
expectedOutput
)
{
int
mfd
=
nf
.
getMaximumFractionDigits
();
RoundingMode
rm
=
nf
.
getRoundingMode
();
String
result
=
nf
.
format
(
someNumber
);
if
(!
result
.
equals
(
expectedOutput
))
{
System
.
out
.
println
();
System
.
out
.
println
(
"========================================"
);
System
.
out
.
println
(
"***Error formatting number value from string : "
+
inputDigits
);
System
.
out
.
println
(
"NumberFormat pattern is : "
+
((
DecimalFormat
)
nf
).
toPattern
());
System
.
out
.
println
(
"Maximum number of fractional digits : "
+
mfd
);
System
.
out
.
println
(
"Fractional rounding digit : "
+
(
mfd
+
1
));
System
.
out
.
println
(
"Position of value relative to tie : "
+
tiePosition
);
System
.
out
.
println
(
"Rounding Mode : "
+
rm
);
System
.
out
.
println
(
"Number self output representation: "
+
someNumber
);
System
.
out
.
println
(
"Error. Formatted result different from expected."
+
"\nExpected output is : \""
+
expectedOutput
+
"\""
+
"\nFormated output is : \""
+
result
+
"\""
);
System
.
out
.
println
(
"========================================"
);
System
.
out
.
println
();
errorCounter
++;
allPassed
=
false
;
}
else
{
testCounter
++;
System
.
out
.
print
(
"Success. Number input :"
+
inputDigits
);
System
.
out
.
print
(
", rounding : "
+
rm
);
System
.
out
.
print
(
", fract digits : "
+
mfd
);
System
.
out
.
print
(
", tie position : "
+
tiePosition
);
System
.
out
.
println
(
", expected : "
+
expectedOutput
);
}
}
public
static
void
main
(
String
[]
args
)
{
// Only the 3 rounding modes below may be impacted by bug 7131459.
// So we do not test the other rounding modes.
RoundingMode
[]
roundingModes
=
{
RoundingMode
.
HALF_DOWN
,
RoundingMode
.
HALF_EVEN
,
RoundingMode
.
HALF_UP
};
// Precise the relative position of input value against its closest tie.
String
[]
tieRelativePositions
=
{
"below"
,
"exact"
,
"above"
,
"below"
,
"exact"
,
"above"
,
"below"
,
"exact"
,
"above"
,
"below"
,
"exact"
,
"above"
};
// =============== Testing double (and thus float) value cases =========
System
.
out
.
println
(
"\n===== testing 3 digits rounding position ====="
);
double
[]
values3FractDigits
=
{
// unimpacting values close to tie, with less than 3 input fract digits
1.115d
,
1.125d
,
1.135d
,
// impacting close to tie values covering all 6 cases
0.3115d
,
0.3125d
,
0.3135d
,
0.6865d
,
0.6875d
,
0.6885d
,
// unimpacting values close to tie, with more than 3 input fract digits
1.46885d
,
2.46875d
,
1.46865d
};
String
[]
inputs3FractDigits
=
{
"1.115d"
,
"1.125d"
,
"1.135d"
,
"0.3115d"
,
"0.3125d"
,
"0.3135d"
,
"0.6865d"
,
"0.6875d"
,
"0.6885d"
,
"1.46885d"
,
"2.46875d"
,
"1.46865d"
};
String
[][]
expected3FractDigits
=
{
{
"1.115"
,
"1.125"
,
"1.135"
,
"0.311"
,
"0.312"
,
"0.314"
,
"0.686"
,
"0.687"
,
"0.689"
,
"1.469"
,
"2.469"
,
"1.469"
},
{
"1.115"
,
"1.125"
,
"1.135"
,
"0.311"
,
"0.312"
,
"0.314"
,
"0.686"
,
"0.688"
,
"0.689"
,
"1.469"
,
"2.469"
,
"1.469"
},
{
"1.115"
,
"1.125"
,
"1.135"
,
"0.311"
,
"0.313"
,
"0.314"
,
"0.686"
,
"0.688"
,
"0.689"
,
"1.469"
,
"2.469"
,
"1.469"
},
};
for
(
int
r
=
0
;
r
<
roundingModes
.
length
;
r
++)
{
NumberFormat
dfDefault
=
NumberFormat
.
getInstance
(
Locale
.
US
);
RoundingMode
rmode
=
roundingModes
[
r
];
dfDefault
.
setRoundingMode
(
rmode
);
System
.
out
.
println
(
"\n----- Now checking "
+
rmode
+
" rounding mode -----"
);
for
(
int
i
=
0
;
i
<
values3FractDigits
.
length
;
i
++)
{
double
d
=
values3FractDigits
[
i
];
String
tiePosition
=
tieRelativePositions
[
i
];
String
input
=
inputs3FractDigits
[
i
];
String
expected
=
expected3FractDigits
[
r
][
i
];
formatOutputTestDouble
(
dfDefault
,
d
,
tiePosition
,
input
,
expected
);
}
}
System
.
out
.
println
(
"\n===== testing 5 digits rounding position ====="
);
double
[]
values5FractDigits
=
{
// unimpacting values close to tie, with less than 5 input fract digits
1.3135d
,
1.3125d
,
1.3115d
,
// impacting values close to tie, covering all 6 cases
1.328115d
,
1.328125d
,
1.328135d
,
1.796865d
,
1.796875d
,
1.796885d
,
// unimpacting values close to tie, with more than 5 input fract digits
1.3281149999999d
,
1.75390625d
,
1.7968750000001d
};
String
[]
inputs5FractDigits
=
{
"1.3135d"
,
"1.3125d"
,
"1.3115d"
,
"1.328115d"
,
"1.328125d"
,
"1.328135d"
,
"1.796865d"
,
"1.796875d"
,
"1.796885d"
,
"1.3281149999999d"
,
"1.75390625d"
,
"1.7968750000001d"
};
String
[][]
expected5FractDigits
=
{
{
"1.3135"
,
"1.3125"
,
"1.3115"
,
"1.32811"
,
"1.32812"
,
"1.32814"
,
"1.79686"
,
"1.79687"
,
"1.79689"
,
"1.32811"
,
"1.75391"
,
"1.79688"
},
{
"1.3135"
,
"1.3125"
,
"1.3115"
,
"1.32811"
,
"1.32812"
,
"1.32814"
,
"1.79686"
,
"1.79688"
,
"1.79689"
,
"1.32811"
,
"1.75391"
,
"1.79688"
},
{
"1.3135"
,
"1.3125"
,
"1.3115"
,
"1.32811"
,
"1.32813"
,
"1.32814"
,
"1.79686"
,
"1.79688"
,
"1.79689"
,
"1.32811"
,
"1.75391"
,
"1.79688"
}
};
for
(
int
r
=
0
;
r
<
roundingModes
.
length
;
r
++)
{
DecimalFormat
df5
=
(
DecimalFormat
)
NumberFormat
.
getInstance
(
Locale
.
US
);
RoundingMode
rmode
=
roundingModes
[
r
];
df5
.
setRoundingMode
(
rmode
);
System
.
out
.
println
(
"\n----- Now checking "
+
rmode
+
" rounding mode -----"
);
df5
.
applyPattern
(
"#,###.#####"
);
for
(
int
i
=
0
;
i
<
values5FractDigits
.
length
;
i
++)
{
double
d
=
values5FractDigits
[
i
];
String
tiePosition
=
tieRelativePositions
[
i
];
String
input
=
inputs5FractDigits
[
i
];
String
expected
=
expected5FractDigits
[
r
][
i
];
formatOutputTestDouble
(
df5
,
d
,
tiePosition
,
input
,
expected
);
}
}
// ==================== Testing long value cases ====================
System
.
out
.
println
(
"\n===== testing long values ====="
);
long
l
=
123456789012345L
;
DecimalFormat
dfLong
=
(
DecimalFormat
)
NumberFormat
.
getInstance
(
Locale
.
US
);
String
tiePosition
=
"exact"
;
String
input
=
"123456789012345L"
;
String
expected
=
"123,456,789,012,345"
;
String
result
=
dfLong
.
format
(
l
);
formatOutputTestLong
(
dfLong
,
l
,
tiePosition
,
input
,
expected
);
dfLong
.
applyPattern
(
"0.###E0"
);
expected
=
"1.235E14"
;
formatOutputTestLong
(
dfLong
,
l
,
tiePosition
,
input
,
expected
);
l
=
123450000000000L
;
input
=
"123450000000000L"
;
expected
=
"1.234E14"
;
formatOutputTestLong
(
dfLong
,
l
,
tiePosition
,
input
,
expected
);
l
=
987750000000000L
;
input
=
"987750000000000L"
;
expected
=
"9.878E14"
;
formatOutputTestLong
(
dfLong
,
l
,
tiePosition
,
input
,
expected
);
dfLong
.
applyPattern
(
"#,###.0E0"
);
l
=
987755000000000L
;
input
=
"987755000000000L"
;
expected
=
"987.76E12"
;
formatOutputTestLong
(
dfLong
,
l
,
tiePosition
,
input
,
expected
);
// ================= Testing BigInteger value cases =================
System
.
out
.
println
(
"\n===== testing BigInteger values ====="
);
String
stringValue
=
"12345678901234567890123456789012345"
;
BigInteger
bi
=
new
BigInteger
(
stringValue
);
DecimalFormat
dfBig
=
(
DecimalFormat
)
NumberFormat
.
getInstance
(
Locale
.
US
);
tiePosition
=
"exact"
;
input
=
stringValue
;
expected
=
"12,345,678,901,234,567,890,123,456,789,012,345"
;
formatOutputTestObject
(
dfBig
,
bi
,
tiePosition
,
input
,
expected
);
dfBig
.
applyPattern
(
"0.###E0"
);
expected
=
"1.235E34"
;
formatOutputTestObject
(
dfBig
,
bi
,
tiePosition
,
input
,
expected
);
stringValue
=
"12345000000000000000000000000000000"
;
input
=
stringValue
;
bi
=
new
BigInteger
(
stringValue
);
expected
=
"1.234E34"
;
formatOutputTestObject
(
dfBig
,
bi
,
tiePosition
,
input
,
expected
);
stringValue
=
"12345000000000000000000000000000001"
;
input
=
stringValue
;
bi
=
new
BigInteger
(
stringValue
);
expected
=
"1.235E34"
;
formatOutputTestObject
(
dfBig
,
bi
,
tiePosition
,
input
,
expected
);
stringValue
=
"98755000000000000000000000000000000"
;
input
=
stringValue
;
bi
=
new
BigInteger
(
stringValue
);
expected
=
"9.876E34"
;
formatOutputTestObject
(
dfBig
,
bi
,
tiePosition
,
input
,
expected
);
dfLong
.
applyPattern
(
"#,###.0E0"
);
stringValue
=
"98775500000000000000000000000000000"
;
input
=
stringValue
;
expected
=
"987.76E34"
;
// =============== Testing BigDecimal value cases ================
System
.
out
.
println
(
"\n===== testing BigDecimal values ====="
);
dfBig
=
(
DecimalFormat
)
NumberFormat
.
getInstance
(
Locale
.
US
);
stringValue
=
"0.68850000000000000088817841970012523233890533447265625"
;
BigDecimal
bd
=
new
BigDecimal
(
stringValue
);
tiePosition
=
"exact"
;
input
=
stringValue
;
expected
=
"0.689"
;
formatOutputTestObject
(
dfBig
,
bd
,
tiePosition
,
input
,
expected
);
stringValue
=
"0.31149999999999999911182158029987476766109466552734375"
;
bd
=
new
BigDecimal
(
stringValue
);
dfBig
.
applyPattern
(
"#,##0.####"
);
tiePosition
=
"exact"
;
input
=
stringValue
;
expected
=
"0.3115"
;
formatOutputTestObject
(
dfBig
,
bd
,
tiePosition
,
input
,
expected
);
// ==================== Printing results and exiting ===================
System
.
out
.
println
();
System
.
out
.
println
(
"==> "
+
testCounter
+
" tests passed successfully"
);
System
.
out
.
println
(
"==> "
+
errorCounter
+
" tests failed"
);
System
.
out
.
println
();
if
(
allPassed
)
{
System
.
out
.
println
(
"Success in formating all the values with the given parameters"
);
}
else
{
String
s
=
"Test failed with "
+
errorCounter
+
" formating error(s)."
;
System
.
out
.
println
(
s
);
throw
new
RuntimeException
(
s
);
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录