Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
core
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
LibreOffice
core
Commits
f175e360
Kaydet (Commit)
f175e360
authored
Tem 22, 2017
tarafından
Chris Sherlock
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
rtl: cleanup equality conditions in math.cxx
Change-Id: I13d898479d883f7905d834c82dc778a9e4078375
üst
f250b04a
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
248 additions
and
153 deletions
+248
-153
math.cxx
sal/rtl/math.cxx
+248
-153
No files found.
sal/rtl/math.cxx
Dosyayı görüntüle @
f175e360
...
@@ -46,23 +46,23 @@ static double const n10s[2][n10Count] = {
...
@@ -46,23 +46,23 @@ static double const n10s[2][n10Count] = {
};
};
// return pow(10.0,nExp) optimized for exponents in the interval [-16,16]
// return pow(10.0,nExp) optimized for exponents in the interval [-16,16]
static
double
getN10Exp
(
int
nExp
)
static
double
getN10Exp
(
int
nExp
)
{
{
if
(
nExp
<
0
)
if
(
nExp
<
0
)
{
{
// && -nExp > 0 necessary for std::numeric_limits<int>::min()
// && -nExp > 0 necessary for std::numeric_limits<int>::min()
// because -nExp = nExp
// because -nExp = nExp
if
(
-
nExp
<=
n10Count
&&
-
nExp
>
0
)
if
(
-
nExp
<=
n10Count
&&
-
nExp
>
0
)
return
n10s
[
1
][
-
nExp
-
1
];
return
n10s
[
1
][
-
nExp
-
1
];
return
pow
(
10.0
,
static_cast
<
double
>
(
nExp
)
);
return
pow
(
10.0
,
static_cast
<
double
>
(
nExp
)
);
}
}
if
(
nExp
>
0
)
if
(
nExp
>
0
)
{
{
if
(
nExp
<=
n10Count
)
if
(
nExp
<=
n10Count
)
return
n10s
[
0
][
nExp
-
1
];
return
n10s
[
0
][
nExp
-
1
];
return
pow
(
10.0
,
static_cast
<
double
>
(
nExp
)
);
return
pow
(
10.0
,
static_cast
<
double
>
(
nExp
));
}
}
// ( nExp == 0 )
return
1.0
;
return
1.0
;
}
}
...
@@ -95,7 +95,7 @@ struct StringTraits
...
@@ -95,7 +95,7 @@ struct StringTraits
sal_Int32
*
pOffset
,
sal_Char
const
*
pChars
,
sal_Int32
*
pOffset
,
sal_Char
const
*
pChars
,
sal_Int32
nLen
)
sal_Int32
nLen
)
{
{
assert
(
pChars
!=
nullptr
);
assert
(
pChars
);
rtl_stringbuffer_insert
(
pBuffer
,
pCapacity
,
*
pOffset
,
pChars
,
nLen
);
rtl_stringbuffer_insert
(
pBuffer
,
pCapacity
,
*
pOffset
,
pChars
,
nLen
);
*
pOffset
+=
nLen
;
*
pOffset
+=
nLen
;
}
}
...
@@ -104,7 +104,7 @@ struct StringTraits
...
@@ -104,7 +104,7 @@ struct StringTraits
sal_Int32
*
pOffset
,
sal_Char
const
*
pStr
,
sal_Int32
*
pOffset
,
sal_Char
const
*
pStr
,
sal_Int32
nLen
)
sal_Int32
nLen
)
{
{
assert
(
pStr
!=
nullptr
);
assert
(
pStr
);
rtl_stringbuffer_insert
(
pBuffer
,
pCapacity
,
*
pOffset
,
pStr
,
nLen
);
rtl_stringbuffer_insert
(
pBuffer
,
pCapacity
,
*
pOffset
,
pStr
,
nLen
);
*
pOffset
+=
nLen
;
*
pOffset
+=
nLen
;
}
}
...
@@ -132,7 +132,7 @@ struct UStringTraits
...
@@ -132,7 +132,7 @@ struct UStringTraits
sal_Int32
*
pCapacity
,
sal_Int32
*
pOffset
,
sal_Int32
*
pCapacity
,
sal_Int32
*
pOffset
,
sal_Unicode
const
*
pChars
,
sal_Int32
nLen
)
sal_Unicode
const
*
pChars
,
sal_Int32
nLen
)
{
{
assert
(
pChars
!=
nullptr
);
assert
(
pChars
);
rtl_uStringbuffer_insert
(
pBuffer
,
pCapacity
,
*
pOffset
,
pChars
,
nLen
);
rtl_uStringbuffer_insert
(
pBuffer
,
pCapacity
,
*
pOffset
,
pChars
,
nLen
);
*
pOffset
+=
nLen
;
*
pOffset
+=
nLen
;
}
}
...
@@ -153,10 +153,10 @@ struct UStringTraits
...
@@ -153,10 +153,10 @@ struct UStringTraits
bool
isRepresentableInteger
(
double
fAbsValue
)
bool
isRepresentableInteger
(
double
fAbsValue
)
{
{
assert
(
fAbsValue
>=
0.0
);
assert
(
fAbsValue
>=
0.0
);
const
sal_Int64
kMaxInt
=
(
static_cast
<
sal_Int64
>
(
1
)
<<
53
)
-
1
;
const
sal_Int64
kMaxInt
=
(
static_cast
<
sal_Int64
>
(
1
)
<<
53
)
-
1
;
if
(
fAbsValue
<=
static_cast
<
double
>
(
kMaxInt
))
if
(
fAbsValue
<=
static_cast
<
double
>
(
kMaxInt
))
{
{
sal_Int64
nInt
=
static_cast
<
sal_Int64
>
(
fAbsValue
);
sal_Int64
nInt
=
static_cast
<
sal_Int64
>
(
fAbsValue
);
// Check the integer range again because double comparison may yield
// Check the integer range again because double comparison may yield
// true within the precision range.
// true within the precision range.
// XXX loplugin:fpcomparison complains about floating-point comparison
// XXX loplugin:fpcomparison complains about floating-point comparison
...
@@ -164,7 +164,7 @@ bool isRepresentableInteger(double fAbsValue)
...
@@ -164,7 +164,7 @@ bool isRepresentableInteger(double fAbsValue)
// this here.
// this here.
double
fInt
;
double
fInt
;
return
(
nInt
<=
kMaxInt
&&
return
(
nInt
<=
kMaxInt
&&
(
!
((
fInt
=
static_cast
<
double
>
(
nInt
))
<
fAbsValue
)
&&
!
(
fInt
>
fAbsValue
)));
(
!
((
fInt
=
static_cast
<
double
>
(
nInt
))
<
fAbsValue
)
&&
!
(
fInt
>
fAbsValue
)));
}
}
return
false
;
return
false
;
}
}
...
@@ -185,20 +185,22 @@ inline void doubleToString(typename T::String ** pResult,
...
@@ -185,20 +185,22 @@ inline void doubleToString(typename T::String ** pResult,
// sign adjustment, instead of testing for fValue<0.0 this will also fetch
// sign adjustment, instead of testing for fValue<0.0 this will also fetch
// -0.0
// -0.0
bool
bSign
=
rtl
::
math
::
isSignBitSet
(
fValue
);
bool
bSign
=
rtl
::
math
::
isSignBitSet
(
fValue
);
if
(
bSign
)
if
(
bSign
)
fValue
=
-
fValue
;
fValue
=
-
fValue
;
if
(
rtl
::
math
::
isNan
(
fValue
)
)
if
(
rtl
::
math
::
isNan
(
fValue
)
)
{
{
// #i112652# XMLSchema-2
// #i112652# XMLSchema-2
sal_Int32
nCapacity
=
RTL_CONSTASCII_LENGTH
(
"NaN"
);
sal_Int32
nCapacity
=
RTL_CONSTASCII_LENGTH
(
"NaN"
);
if
(
pResultCapacity
==
nullptr
)
if
(
!
pResultCapacity
)
{
{
pResultCapacity
=
&
nCapacity
;
pResultCapacity
=
&
nCapacity
;
T
::
createBuffer
(
pResult
,
pResultCapacity
);
T
::
createBuffer
(
pResult
,
pResultCapacity
);
nResultOffset
=
0
;
nResultOffset
=
0
;
}
}
T
::
appendAscii
(
pResult
,
pResultCapacity
,
&
nResultOffset
,
T
::
appendAscii
(
pResult
,
pResultCapacity
,
&
nResultOffset
,
RTL_CONSTASCII_STRINGPARAM
(
"NaN"
));
RTL_CONSTASCII_STRINGPARAM
(
"NaN"
));
...
@@ -206,19 +208,21 @@ inline void doubleToString(typename T::String ** pResult,
...
@@ -206,19 +208,21 @@ inline void doubleToString(typename T::String ** pResult,
}
}
bool
bHuge
=
fValue
==
HUGE_VAL
;
// g++ 3.0.1 requires it this way...
bool
bHuge
=
fValue
==
HUGE_VAL
;
// g++ 3.0.1 requires it this way...
if
(
bHuge
||
rtl
::
math
::
isInf
(
fValue
)
)
if
(
bHuge
||
rtl
::
math
::
isInf
(
fValue
)
)
{
{
// #i112652# XMLSchema-2
// #i112652# XMLSchema-2
sal_Int32
nCapacity
=
RTL_CONSTASCII_LENGTH
(
"-INF"
);
sal_Int32
nCapacity
=
RTL_CONSTASCII_LENGTH
(
"-INF"
);
if
(
pResultCapacity
==
nullptr
)
if
(
!
pResultCapacity
)
{
{
pResultCapacity
=
&
nCapacity
;
pResultCapacity
=
&
nCapacity
;
T
::
createBuffer
(
pResult
,
pResultCapacity
);
T
::
createBuffer
(
pResult
,
pResultCapacity
);
nResultOffset
=
0
;
nResultOffset
=
0
;
}
}
if
(
bSign
)
if
(
bSign
)
T
::
appendAscii
(
pResult
,
pResultCapacity
,
&
nResultOffset
,
T
::
appendAscii
(
pResult
,
pResultCapacity
,
&
nResultOffset
,
RTL_CONSTASCII_STRINGPARAM
(
"-"
));
RTL_CONSTASCII_STRINGPARAM
(
"-"
));
T
::
appendAscii
(
pResult
,
pResultCapacity
,
&
nResultOffset
,
T
::
appendAscii
(
pResult
,
pResultCapacity
,
&
nResultOffset
,
RTL_CONSTASCII_STRINGPARAM
(
"INF"
));
RTL_CONSTASCII_STRINGPARAM
(
"INF"
));
...
@@ -227,31 +231,34 @@ inline void doubleToString(typename T::String ** pResult,
...
@@ -227,31 +231,34 @@ inline void doubleToString(typename T::String ** pResult,
// Use integer representation for integer values that fit into the
// Use integer representation for integer values that fit into the
// mantissa (1.((2^53)-1)) with a precision of 1 for highest accuracy.
// mantissa (1.((2^53)-1)) with a precision of 1 for highest accuracy.
const
sal_Int64
kMaxInt
=
(
static_cast
<
sal_Int64
>
(
1
)
<<
53
)
-
1
;
const
sal_Int64
kMaxInt
=
(
static_cast
<
sal_Int64
>
(
1
)
<<
53
)
-
1
;
if
((
eFormat
==
rtl_math_StringFormat_Automatic
||
if
((
eFormat
==
rtl_math_StringFormat_Automatic
||
eFormat
==
rtl_math_StringFormat_F
)
&&
fValue
<=
static_cast
<
double
>
(
kMaxInt
))
eFormat
==
rtl_math_StringFormat_F
)
&&
fValue
<=
static_cast
<
double
>
(
kMaxInt
))
{
{
sal_Int64
nInt
=
static_cast
<
sal_Int64
>
(
fValue
);
sal_Int64
nInt
=
static_cast
<
sal_Int64
>
(
fValue
);
// Check the integer range again because double comparison may yield
// Check the integer range again because double comparison may yield
// true within the precision range.
// true within the precision range.
if
(
nInt
<=
kMaxInt
&&
static_cast
<
double
>
(
nInt
)
==
fValue
)
if
(
nInt
<=
kMaxInt
&&
static_cast
<
double
>
(
nInt
)
==
fValue
)
{
{
if
(
nDecPlaces
==
rtl_math_DecimalPlaces_Max
)
if
(
nDecPlaces
==
rtl_math_DecimalPlaces_Max
)
nDecPlaces
=
0
;
nDecPlaces
=
0
;
else
else
nDecPlaces
=
::
std
::
max
<
sal_Int32
>
(
::
std
::
min
<
sal_Int32
>
(
nDecPlaces
,
15
),
-
15
);
nDecPlaces
=
::
std
::
max
<
sal_Int32
>
(
::
std
::
min
<
sal_Int32
>
(
nDecPlaces
,
15
),
-
15
);
if
(
bEraseTrailingDecZeros
&&
nDecPlaces
>
0
)
if
(
bEraseTrailingDecZeros
&&
nDecPlaces
>
0
)
nDecPlaces
=
0
;
nDecPlaces
=
0
;
// Round before decimal position.
// Round before decimal position.
if
(
nDecPlaces
<
0
)
if
(
nDecPlaces
<
0
)
{
{
sal_Int64
nRounding
=
static_cast
<
sal_Int64
>
(
getN10Exp
(
-
nDecPlaces
-
1
));
sal_Int64
nRounding
=
static_cast
<
sal_Int64
>
(
getN10Exp
(
-
nDecPlaces
-
1
));
sal_Int64
nTemp
=
nInt
/
nRounding
;
sal_Int64
nTemp
=
nInt
/
nRounding
;
int
nDigit
=
nTemp
%
10
;
int
nDigit
=
nTemp
%
10
;
nTemp
/=
10
;
nTemp
/=
10
;
if
(
nDigit
>=
5
)
if
(
nDigit
>=
5
)
++
nTemp
;
++
nTemp
;
nTemp
*=
10
;
nTemp
*=
10
;
nTemp
*=
nRounding
;
nTemp
*=
nRounding
;
nInt
=
nTemp
;
nInt
=
nTemp
;
...
@@ -290,6 +297,7 @@ inline void doubleToString(typename T::String ** pResult,
...
@@ -290,6 +297,7 @@ inline void doubleToString(typename T::String ** pResult,
{
{
::
std
::
swap
(
pBuf
[
i
],
p
[
-
i
-
1
]);
::
std
::
swap
(
pBuf
[
i
],
p
[
-
i
-
1
]);
}
}
// Append decimals.
// Append decimals.
if
(
nDecPlaces
>
0
)
if
(
nDecPlaces
>
0
)
{
{
...
@@ -298,7 +306,7 @@ inline void doubleToString(typename T::String ** pResult,
...
@@ -298,7 +306,7 @@ inline void doubleToString(typename T::String ** pResult,
*
p
++
=
'0'
;
*
p
++
=
'0'
;
}
}
if
(
pResultCapacity
==
nullptr
)
if
(
!
pResultCapacity
)
T
::
createString
(
pResult
,
pBuf
,
p
-
pBuf
);
T
::
createString
(
pResult
,
pBuf
,
p
-
pBuf
);
else
else
T
::
appendChars
(
pResult
,
pResultCapacity
,
&
nResultOffset
,
pBuf
,
p
-
pBuf
);
T
::
appendChars
(
pResult
,
pResultCapacity
,
&
nResultOffset
,
pBuf
,
p
-
pBuf
);
...
@@ -311,23 +319,23 @@ inline void doubleToString(typename T::String ** pResult,
...
@@ -311,23 +319,23 @@ inline void doubleToString(typename T::String ** pResult,
int
nExp
=
0
;
int
nExp
=
0
;
if
(
fValue
>
0.0
)
if
(
fValue
>
0.0
)
{
{
nExp
=
static_cast
<
int
>
(
floor
(
log10
(
fValue
)
)
);
nExp
=
static_cast
<
int
>
(
floor
(
log10
(
fValue
))
);
fValue
/=
getN10Exp
(
nExp
);
fValue
/=
getN10Exp
(
nExp
);
}
}
switch
(
eFormat
)
switch
(
eFormat
)
{
{
case
rtl_math_StringFormat_Automatic
:
case
rtl_math_StringFormat_Automatic
:
{
// E or F depending on exponent magnitude
{
// E or F depending on exponent magnitude
int
nPrec
;
int
nPrec
;
if
(
nExp
<=
-
15
||
nExp
>=
15
)
// #58531# was <-16, >16
if
(
nExp
<=
-
15
||
nExp
>=
15
)
// #58531# was <-16, >16
{
{
nPrec
=
14
;
nPrec
=
14
;
eFormat
=
rtl_math_StringFormat_E
;
eFormat
=
rtl_math_StringFormat_E
;
}
}
else
else
{
{
if
(
nExp
<
14
)
if
(
nExp
<
14
)
{
{
nPrec
=
15
-
nExp
-
1
;
nPrec
=
15
-
nExp
-
1
;
eFormat
=
rtl_math_StringFormat_F
;
eFormat
=
rtl_math_StringFormat_F
;
...
@@ -338,29 +346,33 @@ inline void doubleToString(typename T::String ** pResult,
...
@@ -338,29 +346,33 @@ inline void doubleToString(typename T::String ** pResult,
eFormat
=
rtl_math_StringFormat_F
;
eFormat
=
rtl_math_StringFormat_F
;
}
}
}
}
if
(
nDecPlaces
==
rtl_math_DecimalPlaces_Max
)
if
(
nDecPlaces
==
rtl_math_DecimalPlaces_Max
)
nDecPlaces
=
nPrec
;
nDecPlaces
=
nPrec
;
}
}
break
;
break
;
case
rtl_math_StringFormat_G
:
case
rtl_math_StringFormat_G
:
case
rtl_math_StringFormat_G1
:
case
rtl_math_StringFormat_G1
:
case
rtl_math_StringFormat_G2
:
case
rtl_math_StringFormat_G2
:
{
// G-Point, similar to sprintf %G
{
// G-Point, similar to sprintf %G
if
(
nDecPlaces
==
rtl_math_DecimalPlaces_DefaultSignificance
)
if
(
nDecPlaces
==
rtl_math_DecimalPlaces_DefaultSignificance
)
nDecPlaces
=
6
;
nDecPlaces
=
6
;
if
(
nExp
<
-
4
||
nExp
>=
nDecPlaces
)
if
(
nExp
<
-
4
||
nExp
>=
nDecPlaces
)
{
{
nDecPlaces
=
std
::
max
<
sal_Int32
>
(
1
,
nDecPlaces
-
1
);
nDecPlaces
=
std
::
max
<
sal_Int32
>
(
1
,
nDecPlaces
-
1
);
if
(
eFormat
==
rtl_math_StringFormat_G
)
if
(
eFormat
==
rtl_math_StringFormat_G
)
eFormat
=
rtl_math_StringFormat_E
;
eFormat
=
rtl_math_StringFormat_E
;
else
if
(
eFormat
==
rtl_math_StringFormat_G2
)
else
if
(
eFormat
==
rtl_math_StringFormat_G2
)
eFormat
=
rtl_math_StringFormat_E2
;
eFormat
=
rtl_math_StringFormat_E2
;
else
if
(
eFormat
==
rtl_math_StringFormat_G1
)
else
if
(
eFormat
==
rtl_math_StringFormat_G1
)
eFormat
=
rtl_math_StringFormat_E1
;
eFormat
=
rtl_math_StringFormat_E1
;
}
}
else
else
{
{
nDecPlaces
=
std
::
max
<
sal_Int32
>
(
0
,
nDecPlaces
-
nExp
-
1
);
nDecPlaces
=
std
::
max
<
sal_Int32
>
(
0
,
nDecPlaces
-
nExp
-
1
);
eFormat
=
rtl_math_StringFormat_F
;
eFormat
=
rtl_math_StringFormat_F
;
}
}
}
}
...
@@ -371,17 +383,18 @@ inline void doubleToString(typename T::String ** pResult,
...
@@ -371,17 +383,18 @@ inline void doubleToString(typename T::String ** pResult,
sal_Int32
nDigits
=
nDecPlaces
+
1
;
sal_Int32
nDigits
=
nDecPlaces
+
1
;
if
(
eFormat
==
rtl_math_StringFormat_F
)
if
(
eFormat
==
rtl_math_StringFormat_F
)
nDigits
+=
nExp
;
nDigits
+=
nExp
;
// Round the number
// Round the number
if
(
nDigits
>=
0
)
if
(
nDigits
>=
0
)
{
{
if
(
(
fValue
+=
nRoundVal
[
nDigits
>
15
?
15
:
nDigits
]
)
>=
10
)
if
((
fValue
+=
nRoundVal
[
nDigits
>
15
?
15
:
nDigits
]
)
>=
10
)
{
{
fValue
=
1.0
;
fValue
=
1.0
;
nExp
++
;
nExp
++
;
if
(
eFormat
==
rtl_math_StringFormat_F
)
if
(
eFormat
==
rtl_math_StringFormat_F
)
nDigits
++
;
nDigits
++
;
}
}
}
}
...
@@ -390,16 +403,20 @@ inline void doubleToString(typename T::String ** pResult,
...
@@ -390,16 +403,20 @@ inline void doubleToString(typename T::String ** pResult,
typename
T
::
Char
aBuf
[
nBufMax
];
typename
T
::
Char
aBuf
[
nBufMax
];
typename
T
::
Char
*
pBuf
;
typename
T
::
Char
*
pBuf
;
sal_Int32
nBuf
=
static_cast
<
sal_Int32
>
sal_Int32
nBuf
=
static_cast
<
sal_Int32
>
(
nDigits
<=
0
?
std
::
max
<
sal_Int32
>
(
nDecPlaces
,
abs
(
nExp
)
)
(
nDigits
<=
0
?
std
::
max
<
sal_Int32
>
(
nDecPlaces
,
abs
(
nExp
)
)
:
nDigits
+
nDecPlaces
)
+
10
+
(
pGroups
?
abs
(
nDigits
)
*
2
:
0
);
:
nDigits
+
nDecPlaces
)
+
10
+
(
pGroups
?
abs
(
nDigits
)
*
2
:
0
);
if
(
nBuf
>
nBufMax
)
if
(
nBuf
>
nBufMax
)
{
{
pBuf
=
static_cast
<
typename
T
::
Char
*
>
(
pBuf
=
static_cast
<
typename
T
::
Char
*
>
(
rtl_allocateMemory
(
nBuf
*
sizeof
(
typename
T
::
Char
)));
rtl_allocateMemory
(
nBuf
*
sizeof
(
typename
T
::
Char
)));
OSL_ENSURE
(
pBuf
!=
nullptr
,
"Out of memory"
);
OSL_ENSURE
(
pBuf
,
"Out of memory"
);
}
}
else
else
{
pBuf
=
aBuf
;
pBuf
=
aBuf
;
}
typename
T
::
Char
*
p
=
pBuf
;
typename
T
::
Char
*
p
=
pBuf
;
if
(
bSign
)
if
(
bSign
)
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'-'
);
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'-'
);
...
@@ -408,64 +425,76 @@ inline void doubleToString(typename T::String ** pResult,
...
@@ -408,64 +425,76 @@ inline void doubleToString(typename T::String ** pResult,
int
nDecPos
;
int
nDecPos
;
// Check for F format and number < 1
// Check for F format and number < 1
if
(
eFormat
==
rtl_math_StringFormat_F
)
if
(
eFormat
==
rtl_math_StringFormat_F
)
{
{
if
(
nExp
<
0
)
if
(
nExp
<
0
)
{
{
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'0'
);
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'0'
);
if
(
nDecPlaces
>
0
)
if
(
nDecPlaces
>
0
)
{
{
*
p
++
=
cDecSeparator
;
*
p
++
=
cDecSeparator
;
bHasDec
=
true
;
bHasDec
=
true
;
}
}
sal_Int32
i
=
(
nDigits
<=
0
?
nDecPlaces
:
-
nExp
-
1
);
while
(
(
i
--
)
>
0
)
sal_Int32
i
=
(
nDigits
<=
0
?
nDecPlaces
:
-
nExp
-
1
);
while
((
i
--
)
>
0
)
{
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'0'
);
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'0'
);
}
nDecPos
=
0
;
nDecPos
=
0
;
}
}
else
else
{
nDecPos
=
nExp
+
1
;
nDecPos
=
nExp
+
1
;
}
}
}
else
else
{
nDecPos
=
1
;
nDecPos
=
1
;
}
int
nGrouping
=
0
,
nGroupSelector
=
0
,
nGroupExceed
=
0
;
int
nGrouping
=
0
,
nGroupSelector
=
0
,
nGroupExceed
=
0
;
if
(
nDecPos
>
1
&&
pGroups
&&
pGroups
[
0
]
&&
cGroupSeparator
)
if
(
nDecPos
>
1
&&
pGroups
&&
pGroups
[
0
]
&&
cGroupSeparator
)
{
{
while
(
nGrouping
+
pGroups
[
nGroupSelector
]
<
nDecPos
)
while
(
nGrouping
+
pGroups
[
nGroupSelector
]
<
nDecPos
)
{
{
nGrouping
+=
pGroups
[
nGroupSelector
];
nGrouping
+=
pGroups
[
nGroupSelector
];
if
(
pGroups
[
nGroupSelector
+
1
]
)
if
(
pGroups
[
nGroupSelector
+
1
]
)
{
{
if
(
nGrouping
+
pGroups
[
nGroupSelector
+
1
]
>=
nDecPos
)
if
(
nGrouping
+
pGroups
[
nGroupSelector
+
1
]
>=
nDecPos
)
break
;
// while
break
;
// while
++
nGroupSelector
;
++
nGroupSelector
;
}
}
else
if
(
!
nGroupExceed
)
else
if
(
!
nGroupExceed
)
{
nGroupExceed
=
nGrouping
;
nGroupExceed
=
nGrouping
;
}
}
}
}
}
// print the number
// print the number
if
(
nDigits
>
0
)
if
(
nDigits
>
0
)
{
{
for
(
int
i
=
0
;
;
i
++
)
for
(
int
i
=
0
;
;
i
++
)
{
{
if
(
i
<
15
)
if
(
i
<
15
)
{
{
int
nDigit
;
int
nDigit
;
if
(
nDigits
-
1
==
0
&&
i
>
0
&&
i
<
14
)
if
(
nDigits
-
1
==
0
&&
i
>
0
&&
i
<
14
)
nDigit
=
static_cast
<
int
>
(
floor
(
fValue
nDigit
=
static_cast
<
int
>
(
floor
(
fValue
+
nKorrVal
[
15
-
i
]));
+
nKorrVal
[
15
-
i
]
)
);
else
else
nDigit
=
static_cast
<
int
>
(
fValue
+
1E-15
);
nDigit
=
static_cast
<
int
>
(
fValue
+
1E-15
);
if
(
nDigit
>=
10
)
if
(
nDigit
>=
10
)
{
// after-treatment of up-rounding to the next decade
{
// after-treatment of up-rounding to the next decade
sal_Int32
sLen
=
static_cast
<
long
>
(
p
-
pBuf
)
-
1
;
sal_Int32
sLen
=
static_cast
<
long
>
(
p
-
pBuf
)
-
1
;
if
(
sLen
==
-
1
)
if
(
sLen
==
-
1
)
{
{
p
=
pBuf
;
p
=
pBuf
;
if
(
eFormat
==
rtl_math_StringFormat_F
)
if
(
eFormat
==
rtl_math_StringFormat_F
)
{
{
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'1'
);
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'1'
);
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'0'
);
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'0'
);
...
@@ -486,38 +515,37 @@ inline void doubleToString(typename T::String ** pResult,
...
@@ -486,38 +515,37 @@ inline void doubleToString(typename T::String ** pResult,
typename
T
::
Char
cS
=
pBuf
[
j
];
typename
T
::
Char
cS
=
pBuf
[
j
];
if
(
cS
!=
cDecSeparator
)
if
(
cS
!=
cDecSeparator
)
{
{
if
(
cS
!=
static_cast
<
typename
T
::
Char
>
(
'9'
))
if
(
cS
!=
static_cast
<
typename
T
::
Char
>
(
'9'
))
{
{
pBuf
[
j
]
=
++
cS
;
pBuf
[
j
]
=
++
cS
;
j
=
-
1
;
// break loop
j
=
-
1
;
// break loop
}
}
else
else
{
{
pBuf
[
j
]
pBuf
[
j
]
=
static_cast
<
typename
T
::
Char
>
(
'0'
);
=
static_cast
<
typename
T
::
Char
>
(
'0'
);
if
(
j
==
0
)
if
(
j
==
0
)
{
{
if
(
eFormat
==
rtl_math_StringFormat_F
)
if
(
eFormat
==
rtl_math_StringFormat_F
)
{
// insert '1'
{
// insert '1'
typename
T
::
Char
*
px
=
p
++
;
typename
T
::
Char
*
px
=
p
++
;
while
(
pBuf
<
px
)
while
(
pBuf
<
px
)
{
{
*
px
=
*
(
px
-
1
);
*
px
=
*
(
px
-
1
);
px
--
;
px
--
;
}
}
pBuf
[
0
]
=
static_cast
<
typename
T
::
Char
>
(
'1'
);
pBuf
[
0
]
=
static_cast
<
typename
T
::
Char
>
(
'1'
);
}
}
else
else
{
{
pBuf
[
j
]
=
static_cast
<
pBuf
[
j
]
=
static_cast
<
typename
T
::
Char
>
(
'1'
);
typename
T
::
Char
>
(
'1'
);
nExp
++
;
nExp
++
;
}
}
}
}
}
}
}
}
}
}
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'0'
);
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'0'
);
}
}
fValue
=
0.0
;
fValue
=
0.0
;
...
@@ -526,88 +554,104 @@ inline void doubleToString(typename T::String ** pResult,
...
@@ -526,88 +554,104 @@ inline void doubleToString(typename T::String ** pResult,
{
{
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
nDigit
+
static_cast
<
typename
T
::
Char
>
(
'0'
)
);
nDigit
+
static_cast
<
typename
T
::
Char
>
(
'0'
)
);
fValue
=
(
fValue
-
nDigit
)
*
10.0
;
fValue
=
(
fValue
-
nDigit
)
*
10.0
;
}
}
}
}
else
else
{
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'0'
);
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'0'
);
if
(
!--
nDigits
)
}
if
(
!--
nDigits
)
break
;
// for
break
;
// for
if
(
nDecPos
)
if
(
nDecPos
)
{
{
if
(
!--
nDecPos
)
if
(
!--
nDecPos
)
{
{
*
p
++
=
cDecSeparator
;
*
p
++
=
cDecSeparator
;
bHasDec
=
true
;
bHasDec
=
true
;
}
}
else
if
(
nDecPos
==
nGrouping
)
else
if
(
nDecPos
==
nGrouping
)
{
{
*
p
++
=
cGroupSeparator
;
*
p
++
=
cGroupSeparator
;
nGrouping
-=
pGroups
[
nGroupSelector
];
nGrouping
-=
pGroups
[
nGroupSelector
];
if
(
nGroupSelector
&&
nGrouping
<
nGroupExceed
)
if
(
nGroupSelector
&&
nGrouping
<
nGroupExceed
)
--
nGroupSelector
;
--
nGroupSelector
;
}
}
}
}
}
}
}
}
if
(
!
bHasDec
&&
eFormat
==
rtl_math_StringFormat_F
)
if
(
!
bHasDec
&&
eFormat
==
rtl_math_StringFormat_F
)
{
// nDecPlaces < 0 did round the value
{
// nDecPlaces < 0 did round the value
while
(
--
nDecPos
>
0
)
while
(
--
nDecPos
>
0
)
{
// fill before decimal point
{
// fill before decimal point
if
(
nDecPos
==
nGrouping
)
if
(
nDecPos
==
nGrouping
)
{
{
*
p
++
=
cGroupSeparator
;
*
p
++
=
cGroupSeparator
;
nGrouping
-=
pGroups
[
nGroupSelector
];
nGrouping
-=
pGroups
[
nGroupSelector
];
if
(
nGroupSelector
&&
nGrouping
<
nGroupExceed
)
if
(
nGroupSelector
&&
nGrouping
<
nGroupExceed
)
--
nGroupSelector
;
--
nGroupSelector
;
}
}
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'0'
);
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'0'
);
}
}
}
}
if
(
bEraseTrailingDecZeros
&&
bHasDec
&&
p
>
pBuf
)
if
(
bEraseTrailingDecZeros
&&
bHasDec
&&
p
>
pBuf
)
{
{
while
(
*
(
p
-
1
)
==
static_cast
<
typename
T
::
Char
>
(
'0'
)
)
while
(
*
(
p
-
1
)
==
static_cast
<
typename
T
::
Char
>
(
'0'
))
{
p
--
;
p
--
;
if
(
*
(
p
-
1
)
==
cDecSeparator
)
}
if
(
*
(
p
-
1
)
==
cDecSeparator
)
p
--
;
p
--
;
}
}
// Print the exponent ('E', followed by '+' or '-', followed by exactly
// Print the exponent ('E', followed by '+' or '-', followed by exactly
// three digits for rtl_math_StringFormat_E). The code in
// three digits for rtl_math_StringFormat_E). The code in
// rtl_[u]str_valueOf{Float|Double} relies on this format.
// rtl_[u]str_valueOf{Float|Double} relies on this format.
if
(
eFormat
==
rtl_math_StringFormat_E
||
eFormat
==
rtl_math_StringFormat_E2
||
eFormat
==
rtl_math_StringFormat_E1
)
if
(
eFormat
==
rtl_math_StringFormat_E
||
eFormat
==
rtl_math_StringFormat_E2
||
eFormat
==
rtl_math_StringFormat_E1
)
{
{
if
(
p
==
pBuf
)
if
(
p
==
pBuf
)
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'1'
);
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'1'
);
// maybe no nDigits if nDecPlaces < 0
// maybe no nDigits if nDecPlaces < 0
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'E'
);
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'E'
);
if
(
nExp
<
0
)
if
(
nExp
<
0
)
{
{
nExp
=
-
nExp
;
nExp
=
-
nExp
;
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'-'
);
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'-'
);
}
}
else
else
{
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'+'
);
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
'+'
);
if
(
eFormat
==
rtl_math_StringFormat_E
||
nExp
>=
100
)
}
if
(
eFormat
==
rtl_math_StringFormat_E
||
nExp
>=
100
)
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
nExp
/
100
+
static_cast
<
typename
T
::
Char
>
(
'0'
)
);
nExp
/
100
+
static_cast
<
typename
T
::
Char
>
(
'0'
)
);
nExp
%=
100
;
nExp
%=
100
;
if
(
eFormat
==
rtl_math_StringFormat_E
||
eFormat
==
rtl_math_StringFormat_E2
||
nExp
>=
10
)
if
(
eFormat
==
rtl_math_StringFormat_E
||
eFormat
==
rtl_math_StringFormat_E2
||
nExp
>=
10
)
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
nExp
/
10
+
static_cast
<
typename
T
::
Char
>
(
'0'
)
);
nExp
/
10
+
static_cast
<
typename
T
::
Char
>
(
'0'
)
);
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
*
p
++
=
static_cast
<
typename
T
::
Char
>
(
nExp
%
10
+
static_cast
<
typename
T
::
Char
>
(
'0'
)
);
nExp
%
10
+
static_cast
<
typename
T
::
Char
>
(
'0'
)
);
}
}
if
(
pResultCapacity
==
nullptr
)
if
(
!
pResultCapacity
)
T
::
createString
(
pResult
,
pBuf
,
p
-
pBuf
);
T
::
createString
(
pResult
,
pBuf
,
p
-
pBuf
);
else
else
T
::
appendChars
(
pResult
,
pResultCapacity
,
&
nResultOffset
,
pBuf
,
T
::
appendChars
(
pResult
,
pResultCapacity
,
&
nResultOffset
,
pBuf
,
p
-
pBuf
);
p
-
pBuf
);
if
(
pBuf
!=
&
aBuf
[
0
]
)
if
(
pBuf
!=
&
aBuf
[
0
]
)
rtl_freeMemory
(
pBuf
);
rtl_freeMemory
(
pBuf
);
}
}
...
@@ -670,7 +714,10 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
...
@@ -670,7 +714,10 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
CharT
const
*
p0
=
pBegin
;
CharT
const
*
p0
=
pBegin
;
while
(
p0
!=
pEnd
&&
(
*
p0
==
CharT
(
' '
)
||
*
p0
==
CharT
(
'\t'
)))
while
(
p0
!=
pEnd
&&
(
*
p0
==
CharT
(
' '
)
||
*
p0
==
CharT
(
'\t'
)))
{
++
p0
;
++
p0
;
}
bool
bSign
;
bool
bSign
;
if
(
p0
!=
pEnd
&&
*
p0
==
CharT
(
'-'
))
if
(
p0
!=
pEnd
&&
*
p0
==
CharT
(
'-'
))
{
{
...
@@ -683,11 +730,12 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
...
@@ -683,11 +730,12 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
if
(
p0
!=
pEnd
&&
*
p0
==
CharT
(
'+'
))
if
(
p0
!=
pEnd
&&
*
p0
==
CharT
(
'+'
))
++
p0
;
++
p0
;
}
}
CharT
const
*
p
=
p0
;
CharT
const
*
p
=
p0
;
bool
bDone
=
false
;
bool
bDone
=
false
;
// #i112652# XMLSchema-2
// #i112652# XMLSchema-2
if
(
3
<=
(
pEnd
-
p
)
)
if
(
(
pEnd
-
p
)
>=
3
)
{
{
if
((
CharT
(
'N'
)
==
p
[
0
])
&&
(
CharT
(
'a'
)
==
p
[
1
])
if
((
CharT
(
'N'
)
==
p
[
0
])
&&
(
CharT
(
'a'
)
==
p
[
1
])
&&
(
CharT
(
'N'
)
==
p
[
2
]))
&&
(
CharT
(
'N'
)
==
p
[
2
]))
...
@@ -710,7 +758,9 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
...
@@ -710,7 +758,9 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
{
{
// leading zeros and group separators may be safely ignored
// leading zeros and group separators may be safely ignored
while
(
p
!=
pEnd
&&
(
*
p
==
CharT
(
'0'
)
||
*
p
==
cGroupSeparator
))
while
(
p
!=
pEnd
&&
(
*
p
==
CharT
(
'0'
)
||
*
p
==
cGroupSeparator
))
{
++
p
;
++
p
;
}
CharT
const
*
pFirstSignificant
=
p
;
CharT
const
*
pFirstSignificant
=
p
;
long
nValExp
=
0
;
// carry along exponent of mantissa
long
nValExp
=
0
;
// carry along exponent of mantissa
...
@@ -725,7 +775,9 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
...
@@ -725,7 +775,9 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
++
nValExp
;
++
nValExp
;
}
}
else
if
(
c
!=
cGroupSeparator
)
else
if
(
c
!=
cGroupSeparator
)
{
break
;
break
;
}
}
}
// fraction part of mantissa
// fraction part of mantissa
...
@@ -739,8 +791,10 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
...
@@ -739,8 +791,10 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
--
nFracExp
;
--
nFracExp
;
++
p
;
++
p
;
}
}
if
(
nValExp
==
0
)
if
(
nValExp
==
0
)
nValExp
=
nFracExp
-
1
;
// no integer part => fraction exponent
nValExp
=
nFracExp
-
1
;
// no integer part => fraction exponent
// one decimal digit needs ld(10) ~= 3.32 bits
// one decimal digit needs ld(10) ~= 3.32 bits
static
const
int
nSigs
=
(
DBL_MANT_DIG
/
3
)
+
1
;
static
const
int
nSigs
=
(
DBL_MANT_DIG
/
3
)
+
1
;
int
nDigs
=
0
;
int
nDigs
=
0
;
...
@@ -748,7 +802,9 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
...
@@ -748,7 +802,9 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
{
{
CharT
c
=
*
p
;
CharT
c
=
*
p
;
if
(
!
rtl
::
isAsciiDigit
(
c
))
if
(
!
rtl
::
isAsciiDigit
(
c
))
{
break
;
break
;
}
if
(
nDigs
<
nSigs
)
if
(
nDigs
<
nSigs
)
{
// further digits (more than nSigs) don't have any
{
// further digits (more than nSigs) don't have any
// significance
// significance
...
@@ -757,25 +813,30 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
...
@@ -757,25 +813,30 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
++
nDigs
;
++
nDigs
;
}
}
}
}
if
(
fFrac
!=
0.0
)
if
(
fFrac
!=
0.0
)
{
fVal
+=
rtl
::
math
::
pow10Exp
(
fFrac
,
nFracExp
);
fVal
+=
rtl
::
math
::
pow10Exp
(
fFrac
,
nFracExp
);
else
if
(
nValExp
<
0
)
}
else
if
(
nValExp
<
0
)
{
{
if
(
pFirstSignificant
+
1
==
p
)
if
(
pFirstSignificant
+
1
==
p
)
{
{
// No digit at all, only separator(s) without integer or
// No digit at all, only separator(s) without integer or
// fraction part. Bail out. No number. No error.
// fraction part. Bail out. No number. No error.
if
(
pStatus
!=
nullptr
)
if
(
pStatus
)
*
pStatus
=
eStatus
;
*
pStatus
=
eStatus
;
if
(
pParsedEnd
!=
nullptr
)
if
(
pParsedEnd
)
*
pParsedEnd
=
pBegin
;
*
pParsedEnd
=
pBegin
;
return
fVal
;
return
fVal
;
}
}
nValExp
=
0
;
// no digit other than 0 after decimal point
nValExp
=
0
;
// no digit other than 0 after decimal point
}
}
}
}
if
(
nValExp
>
0
)
if
(
nValExp
>
0
)
--
nValExp
;
// started with offset +1 at the first mantissa digit
--
nValExp
;
// started with offset +1 at the first mantissa digit
// Exponent
// Exponent
...
@@ -800,7 +861,10 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
...
@@ -800,7 +861,10 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
{
// no matter what follows, zero stays zero, but carry on the
{
// no matter what follows, zero stays zero, but carry on the
// offset
// offset
while
(
p
!=
pEnd
&&
rtl
::
isAsciiDigit
(
*
p
))
while
(
p
!=
pEnd
&&
rtl
::
isAsciiDigit
(
*
p
))
{
++
p
;
++
p
;
}
if
(
p
==
pFirstExpDigit
)
if
(
p
==
pFirstExpDigit
)
{
// no digits in exponent, reset end of scan
{
// no digits in exponent, reset end of scan
p
=
pExponent
;
p
=
pExponent
;
...
@@ -815,16 +879,20 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
...
@@ -815,16 +879,20 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
CharT
c
=
*
p
;
CharT
c
=
*
p
;
if
(
!
rtl
::
isAsciiDigit
(
c
))
if
(
!
rtl
::
isAsciiDigit
(
c
))
break
;
break
;
int
i
=
c
-
CharT
(
'0'
);
int
i
=
c
-
CharT
(
'0'
);
if
(
long10Overflow
(
nExp
,
i
)
)
if
(
long10Overflow
(
nExp
,
i
)
)
bOverflow
=
true
;
bOverflow
=
true
;
else
else
nExp
=
nExp
*
10
+
i
;
nExp
=
nExp
*
10
+
i
;
}
}
if
(
nExp
)
if
(
nExp
)
{
{
if
(
bExpSign
)
if
(
bExpSign
)
nExp
=
-
nExp
;
nExp
=
-
nExp
;
long
nAllExp
=
(
bOverflow
?
0
:
nExp
+
nValExp
);
long
nAllExp
=
(
bOverflow
?
0
:
nExp
+
nValExp
);
if
(
nAllExp
>
DBL_MAX_10_EXP
||
(
bOverflow
&&
!
bExpSign
)
)
if
(
nAllExp
>
DBL_MAX_10_EXP
||
(
bOverflow
&&
!
bExpSign
)
)
{
// overflow
{
// overflow
...
@@ -843,7 +911,9 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
...
@@ -843,7 +911,9 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
fVal
=
rtl
::
math
::
pow10Exp
(
fVal
,
nAllExp
);
fVal
=
rtl
::
math
::
pow10Exp
(
fVal
,
nAllExp
);
}
}
else
else
{
fVal
=
rtl
::
math
::
pow10Exp
(
fVal
,
nExp
);
// normal
fVal
=
rtl
::
math
::
pow10Exp
(
fVal
,
nExp
);
// normal
}
}
}
else
if
(
p
==
pFirstExpDigit
)
else
if
(
p
==
pFirstExpDigit
)
{
// no digits in exponent, reset end of scan
{
// no digits in exponent, reset end of scan
...
@@ -877,14 +947,18 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
...
@@ -877,14 +947,18 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
double
sd
;
double
sd
;
sal_math_Double
md
;
sal_math_Double
md
;
}
m
;
}
m
;
m
.
sd
=
fVal
;
m
.
sd
=
fVal
;
m
.
md
.
w32_parts
.
msw
|=
0x80000000
;
// create negative NaN
m
.
md
.
w32_parts
.
msw
|=
0x80000000
;
// create negative NaN
fVal
=
m
.
sd
;
fVal
=
m
.
sd
;
bSign
=
false
;
// don't negate again
bSign
=
false
;
// don't negate again
}
}
// Eat any further digits:
// Eat any further digits:
while
(
p
!=
pEnd
&&
rtl
::
isAsciiDigit
(
*
p
))
while
(
p
!=
pEnd
&&
rtl
::
isAsciiDigit
(
*
p
))
{
++
p
;
++
p
;
}
}
}
}
}
}
}
...
@@ -892,15 +966,16 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
...
@@ -892,15 +966,16 @@ inline double stringToDouble(CharT const * pBegin, CharT const * pEnd,
// overflow also if more than DBL_MAX_10_EXP digits without decimal
// overflow also if more than DBL_MAX_10_EXP digits without decimal
// separator, or 0. and more than DBL_MIN_10_EXP digits, ...
// separator, or 0. and more than DBL_MIN_10_EXP digits, ...
bool
bHuge
=
fVal
==
HUGE_VAL
;
// g++ 3.0.1 requires it this way...
bool
bHuge
=
fVal
==
HUGE_VAL
;
// g++ 3.0.1 requires it this way...
if
(
bHuge
)
if
(
bHuge
)
eStatus
=
rtl_math_ConversionStatus_OutOfRange
;
eStatus
=
rtl_math_ConversionStatus_OutOfRange
;
if
(
bSign
)
if
(
bSign
)
fVal
=
-
fVal
;
fVal
=
-
fVal
;
if
(
pStatus
!=
nullptr
)
if
(
pStatus
)
*
pStatus
=
eStatus
;
*
pStatus
=
eStatus
;
if
(
pParsedEnd
!=
nullptr
)
if
(
pParsedEnd
)
*
pParsedEnd
=
p
==
p0
?
pBegin
:
p
;
*
pParsedEnd
=
p
==
p0
?
pBegin
:
p
;
return
fVal
;
return
fVal
;
...
@@ -942,26 +1017,25 @@ double SAL_CALL rtl_math_round(double fValue, int nDecPlaces,
...
@@ -942,26 +1017,25 @@ double SAL_CALL rtl_math_round(double fValue, int nDecPlaces,
{
{
OSL_ASSERT
(
nDecPlaces
>=
-
20
&&
nDecPlaces
<=
20
);
OSL_ASSERT
(
nDecPlaces
>=
-
20
&&
nDecPlaces
<=
20
);
if
(
fValue
==
0.0
)
if
(
fValue
==
0.0
)
return
fValue
;
return
fValue
;
// sign adjustment
// sign adjustment
bool
bSign
=
rtl
::
math
::
isSignBitSet
(
fValue
);
bool
bSign
=
rtl
::
math
::
isSignBitSet
(
fValue
);
if
(
bSign
)
if
(
bSign
)
fValue
=
-
fValue
;
fValue
=
-
fValue
;
double
fFac
=
0
;
double
fFac
=
0
;
if
(
nDecPlaces
!=
0
)
if
(
nDecPlaces
!=
0
)
{
{
// max 20 decimals, we don't have unlimited precision
// max 20 decimals, we don't have unlimited precision
// #38810# and no overflow on fValue*=fFac
// #38810# and no overflow on fValue*=fFac
if
(
nDecPlaces
<
-
20
||
20
<
nDecPlaces
||
fValue
>
(
DBL_MAX
/
1e20
)
)
if
(
nDecPlaces
<
-
20
||
20
<
nDecPlaces
||
fValue
>
(
DBL_MAX
/
1e20
)
)
return
bSign
?
-
fValue
:
fValue
;
return
bSign
?
-
fValue
:
fValue
;
fFac
=
getN10Exp
(
nDecPlaces
);
fFac
=
getN10Exp
(
nDecPlaces
);
fValue
*=
fFac
;
fValue
*=
fFac
;
}
}
//else //! uninitialized fFac, not needed
switch
(
eMode
)
switch
(
eMode
)
{
{
...
@@ -972,41 +1046,44 @@ double SAL_CALL rtl_math_round(double fValue, int nDecPlaces,
...
@@ -972,41 +1046,44 @@ double SAL_CALL rtl_math_round(double fValue, int nDecPlaces,
nExp
=
static_cast
<
int
>
(
floor
(
log10
(
fValue
)
)
);
nExp
=
static_cast
<
int
>
(
floor
(
log10
(
fValue
)
)
);
else
else
nExp
=
0
;
nExp
=
0
;
int
nIndex
=
15
-
nExp
;
int
nIndex
=
15
-
nExp
;
if
(
nIndex
>
15
)
if
(
nIndex
>
15
)
nIndex
=
15
;
nIndex
=
15
;
else
if
(
nIndex
<=
1
)
else
if
(
nIndex
<=
1
)
nIndex
=
0
;
nIndex
=
0
;
fValue
=
floor
(
fValue
+
0.5
+
nKorrVal
[
nIndex
]
);
fValue
=
floor
(
fValue
+
0.5
+
nKorrVal
[
nIndex
]);
}
}
break
;
break
;
case
rtl_math_RoundingMode_Down
:
case
rtl_math_RoundingMode_Down
:
fValue
=
rtl
::
math
::
approxFloor
(
fValue
);
fValue
=
rtl
::
math
::
approxFloor
(
fValue
);
break
;
break
;
case
rtl_math_RoundingMode_Up
:
case
rtl_math_RoundingMode_Up
:
fValue
=
rtl
::
math
::
approxCeil
(
fValue
);
fValue
=
rtl
::
math
::
approxCeil
(
fValue
);
break
;
break
;
case
rtl_math_RoundingMode_Floor
:
case
rtl_math_RoundingMode_Floor
:
fValue
=
bSign
?
rtl
::
math
::
approxCeil
(
fValue
)
fValue
=
bSign
?
rtl
::
math
::
approxCeil
(
fValue
)
:
rtl
::
math
::
approxFloor
(
fValue
);
:
rtl
::
math
::
approxFloor
(
fValue
);
break
;
break
;
case
rtl_math_RoundingMode_Ceiling
:
case
rtl_math_RoundingMode_Ceiling
:
fValue
=
bSign
?
rtl
::
math
::
approxFloor
(
fValue
)
fValue
=
bSign
?
rtl
::
math
::
approxFloor
(
fValue
)
:
rtl
::
math
::
approxCeil
(
fValue
);
:
rtl
::
math
::
approxCeil
(
fValue
);
break
;
break
;
case
rtl_math_RoundingMode_HalfDown
:
case
rtl_math_RoundingMode_HalfDown
:
{
{
double
f
=
floor
(
fValue
);
double
f
=
floor
(
fValue
);
fValue
=
((
fValue
-
f
)
<=
0.5
)
?
f
:
ceil
(
fValue
);
fValue
=
((
fValue
-
f
)
<=
0.5
)
?
f
:
ceil
(
fValue
);
}
}
break
;
break
;
case
rtl_math_RoundingMode_HalfUp
:
case
rtl_math_RoundingMode_HalfUp
:
{
{
double
f
=
floor
(
fValue
);
double
f
=
floor
(
fValue
);
fValue
=
((
fValue
-
f
)
<
0.5
)
?
f
:
ceil
(
fValue
);
fValue
=
((
fValue
-
f
)
<
0.5
)
?
f
:
ceil
(
fValue
);
}
}
break
;
break
;
case
rtl_math_RoundingMode_HalfEven
:
case
rtl_math_RoundingMode_HalfEven
:
#if defined FLT_ROUNDS
#if defined FLT_ROUNDS
/*
/*
Use fast version. FLT_ROUNDS may be defined to a function by some compilers!
Use fast version. FLT_ROUNDS may be defined to a function by some compilers!
...
@@ -1021,7 +1098,7 @@ double SAL_CALL rtl_math_round(double fValue, int nDecPlaces,
...
@@ -1021,7 +1098,7 @@ double SAL_CALL rtl_math_round(double fValue, int nDecPlaces,
volatile: prevent compiler from being too smart
volatile: prevent compiler from being too smart
*/
*/
if
(
FLT_ROUNDS
==
1
)
if
(
FLT_ROUNDS
==
1
)
{
{
volatile
double
x
=
fValue
+
1.0
/
DBL_EPSILON
;
volatile
double
x
=
fValue
+
1.0
/
DBL_EPSILON
;
fValue
=
x
-
1.0
/
DBL_EPSILON
;
fValue
=
x
-
1.0
/
DBL_EPSILON
;
...
@@ -1029,9 +1106,11 @@ double SAL_CALL rtl_math_round(double fValue, int nDecPlaces,
...
@@ -1029,9 +1106,11 @@ double SAL_CALL rtl_math_round(double fValue, int nDecPlaces,
else
else
#endif // FLT_ROUNDS
#endif // FLT_ROUNDS
{
{
double
f
=
floor
(
fValue
);
double
f
=
floor
(
fValue
);
if
(
(
fValue
-
f
)
!=
0.5
)
if
((
fValue
-
f
)
!=
0.5
)
{
fValue
=
floor
(
fValue
+
0.5
);
fValue
=
floor
(
fValue
+
0.5
);
}
else
else
{
{
double
g
=
f
/
2.0
;
double
g
=
f
/
2.0
;
...
@@ -1044,7 +1123,7 @@ double SAL_CALL rtl_math_round(double fValue, int nDecPlaces,
...
@@ -1044,7 +1123,7 @@ double SAL_CALL rtl_math_round(double fValue, int nDecPlaces,
break
;
break
;
}
}
if
(
nDecPlaces
!=
0
)
if
(
nDecPlaces
!=
0
)
fValue
/=
fFac
;
fValue
/=
fFac
;
return
bSign
?
-
fValue
:
fValue
;
return
bSign
?
-
fValue
:
fValue
;
...
@@ -1052,35 +1131,39 @@ double SAL_CALL rtl_math_round(double fValue, int nDecPlaces,
...
@@ -1052,35 +1131,39 @@ double SAL_CALL rtl_math_round(double fValue, int nDecPlaces,
double
SAL_CALL
rtl_math_pow10Exp
(
double
fValue
,
int
nExp
)
SAL_THROW_EXTERN_C
()
double
SAL_CALL
rtl_math_pow10Exp
(
double
fValue
,
int
nExp
)
SAL_THROW_EXTERN_C
()
{
{
return
fValue
*
getN10Exp
(
nExp
);
return
fValue
*
getN10Exp
(
nExp
);
}
}
double
SAL_CALL
rtl_math_approxValue
(
double
fValue
)
SAL_THROW_EXTERN_C
()
double
SAL_CALL
rtl_math_approxValue
(
double
fValue
)
SAL_THROW_EXTERN_C
()
{
{
if
(
fValue
==
0.0
||
fValue
==
HUGE_VAL
||
!::
rtl
::
math
::
isFinite
(
fValue
))
if
(
fValue
==
0.0
||
fValue
==
HUGE_VAL
||
!::
rtl
::
math
::
isFinite
(
fValue
))
{
// We don't handle these conditions. Bail out.
// We don't handle these conditions. Bail out.
return
fValue
;
return
fValue
;
}
double
fOrigValue
=
fValue
;
double
fOrigValue
=
fValue
;
bool
bSign
=
::
rtl
::
math
::
isSignBitSet
(
fValue
);
bool
bSign
=
::
rtl
::
math
::
isSignBitSet
(
fValue
);
if
(
bSign
)
if
(
bSign
)
fValue
=
-
fValue
;
fValue
=
-
fValue
;
int
nExp
=
static_cast
<
int
>
(
floor
(
log10
(
fValue
)));
int
nExp
=
static_cast
<
int
>
(
floor
(
log10
(
fValue
)));
nExp
=
14
-
nExp
;
nExp
=
14
-
nExp
;
double
fExpValue
=
getN10Exp
(
nExp
);
double
fExpValue
=
getN10Exp
(
nExp
);
fValue
*=
fExpValue
;
fValue
*=
fExpValue
;
// If the original value was near DBL_MIN we got an overflow. Restore and
// If the original value was near DBL_MIN we got an overflow. Restore and
// bail out.
// bail out.
if
(
!
rtl
::
math
::
isFinite
(
fValue
))
if
(
!
rtl
::
math
::
isFinite
(
fValue
))
return
fOrigValue
;
return
fOrigValue
;
fValue
=
rtl_math_round
(
fValue
,
0
,
rtl_math_RoundingMode_Corrected
);
fValue
=
rtl_math_round
(
fValue
,
0
,
rtl_math_RoundingMode_Corrected
);
fValue
/=
fExpValue
;
fValue
/=
fExpValue
;
// If the original value was near DBL_MAX we got an overflow. Restore and
// If the original value was near DBL_MAX we got an overflow. Restore and
// bail out.
// bail out.
if
(
!
rtl
::
math
::
isFinite
(
fValue
))
if
(
!
rtl
::
math
::
isFinite
(
fValue
))
return
fOrigValue
;
return
fOrigValue
;
return
bSign
?
-
fValue
:
fValue
;
return
bSign
?
-
fValue
:
fValue
;
...
@@ -1090,47 +1173,54 @@ bool SAL_CALL rtl_math_approxEqual(double a, double b) SAL_THROW_EXTERN_C()
...
@@ -1090,47 +1173,54 @@ bool SAL_CALL rtl_math_approxEqual(double a, double b) SAL_THROW_EXTERN_C()
{
{
static
const
double
e48
=
1.0
/
(
16777216.0
*
16777216.0
);
static
const
double
e48
=
1.0
/
(
16777216.0
*
16777216.0
);
static
const
double
e44
=
e48
*
16.0
;
static
const
double
e44
=
e48
*
16.0
;
if
(
a
==
b
)
if
(
a
==
b
)
return
true
;
return
true
;
if
(
a
==
0.0
||
b
==
0.0
)
if
(
a
==
0.0
||
b
==
0.0
)
return
false
;
return
false
;
const
double
d
=
fabs
(
a
-
b
);
const
double
d
=
fabs
(
a
-
b
);
if
(
!
rtl
::
math
::
isFinite
(
d
))
if
(
!
rtl
::
math
::
isFinite
(
d
))
return
false
;
// Nan or Inf involved
return
false
;
// Nan or Inf involved
if
(
d
>
((
a
=
fabs
(
a
))
*
e44
)
||
d
>
((
b
=
fabs
(
b
))
*
e44
))
if
(
d
>
((
a
=
fabs
(
a
))
*
e44
)
||
d
>
((
b
=
fabs
(
b
))
*
e44
))
return
false
;
return
false
;
if
(
isRepresentableInteger
(
d
)
&&
isRepresentableInteger
(
a
)
&&
isRepresentableInteger
(
b
))
if
(
isRepresentableInteger
(
d
)
&&
isRepresentableInteger
(
a
)
&&
isRepresentableInteger
(
b
))
return
false
;
// special case for representable integers.
return
false
;
// special case for representable integers.
return
(
d
<
a
*
e48
&&
d
<
b
*
e48
);
return
(
d
<
a
*
e48
&&
d
<
b
*
e48
);
}
}
double
SAL_CALL
rtl_math_expm1
(
double
fValue
)
SAL_THROW_EXTERN_C
()
double
SAL_CALL
rtl_math_expm1
(
double
fValue
)
SAL_THROW_EXTERN_C
()
{
{
return
expm1
(
fValue
);
return
expm1
(
fValue
);
}
}
double
SAL_CALL
rtl_math_log1p
(
double
fValue
)
SAL_THROW_EXTERN_C
()
double
SAL_CALL
rtl_math_log1p
(
double
fValue
)
SAL_THROW_EXTERN_C
()
{
{
#ifdef __APPLE__
#ifdef __APPLE__
if
(
fValue
==
-
0.0
)
if
(
fValue
==
-
0.0
)
return
fValue
;
// OS X 10.8 libc returns 0.0 for -0.0
return
fValue
;
// OS X 10.8 libc returns 0.0 for -0.0
#endif
#endif
return
log1p
(
fValue
);
return
log1p
(
fValue
);
}
}
double
SAL_CALL
rtl_math_atanh
(
double
fValue
)
SAL_THROW_EXTERN_C
()
double
SAL_CALL
rtl_math_atanh
(
double
fValue
)
SAL_THROW_EXTERN_C
()
{
{
return
0.5
*
rtl_math_log1p
(
2.0
*
fValue
/
(
1.0
-
fValue
)
);
return
0.5
*
rtl_math_log1p
(
2.0
*
fValue
/
(
1.0
-
fValue
)
);
}
}
/** Parent error function (erf) */
/** Parent error function (erf) */
double
SAL_CALL
rtl_math_erf
(
double
x
)
SAL_THROW_EXTERN_C
()
double
SAL_CALL
rtl_math_erf
(
double
x
)
SAL_THROW_EXTERN_C
()
{
{
return
erf
(
x
);
return
erf
(
x
);
}
}
/** Parent complementary error function (erfc) */
/** Parent complementary error function (erfc) */
double
SAL_CALL
rtl_math_erfc
(
double
x
)
SAL_THROW_EXTERN_C
()
double
SAL_CALL
rtl_math_erfc
(
double
x
)
SAL_THROW_EXTERN_C
()
{
{
return
erfc
(
x
);
return
erfc
(
x
);
}
}
...
@@ -1138,7 +1228,7 @@ double SAL_CALL rtl_math_erfc( double x ) SAL_THROW_EXTERN_C()
...
@@ -1138,7 +1228,7 @@ double SAL_CALL rtl_math_erfc( double x ) SAL_THROW_EXTERN_C()
/** improved accuracy of asinh for |x| large and for x near zero
/** improved accuracy of asinh for |x| large and for x near zero
@see #i97605#
@see #i97605#
*/
*/
double
SAL_CALL
rtl_math_asinh
(
double
fX
)
SAL_THROW_EXTERN_C
()
double
SAL_CALL
rtl_math_asinh
(
double
fX
)
SAL_THROW_EXTERN_C
()
{
{
if
(
fX
==
0.0
)
if
(
fX
==
0.0
)
return
0.0
;
return
0.0
;
...
@@ -1149,8 +1239,10 @@ double SAL_CALL rtl_math_asinh( double fX ) SAL_THROW_EXTERN_C()
...
@@ -1149,8 +1239,10 @@ double SAL_CALL rtl_math_asinh( double fX ) SAL_THROW_EXTERN_C()
fX
=
-
fX
;
fX
=
-
fX
;
fSign
=
-
1.0
;
fSign
=
-
1.0
;
}
}
if
(
fX
<
0.125
)
if
(
fX
<
0.125
)
return
fSign
*
rtl_math_log1p
(
fX
+
fX
*
fX
/
(
1.0
+
sqrt
(
1.0
+
fX
*
fX
)));
return
fSign
*
rtl_math_log1p
(
fX
+
fX
*
fX
/
(
1.0
+
sqrt
(
1.0
+
fX
*
fX
)));
if
(
fX
<
1.25e7
)
if
(
fX
<
1.25e7
)
return
fSign
*
log
(
fX
+
sqrt
(
1.0
+
fX
*
fX
));
return
fSign
*
log
(
fX
+
sqrt
(
1.0
+
fX
*
fX
));
...
@@ -1160,10 +1252,10 @@ double SAL_CALL rtl_math_asinh( double fX ) SAL_THROW_EXTERN_C()
...
@@ -1160,10 +1252,10 @@ double SAL_CALL rtl_math_asinh( double fX ) SAL_THROW_EXTERN_C()
/** improved accuracy of acosh for x large and for x near 1
/** improved accuracy of acosh for x large and for x near 1
@see #i97605#
@see #i97605#
*/
*/
double
SAL_CALL
rtl_math_acosh
(
double
fX
)
SAL_THROW_EXTERN_C
()
double
SAL_CALL
rtl_math_acosh
(
double
fX
)
SAL_THROW_EXTERN_C
()
{
{
volatile
double
fZ
=
fX
-
1.0
;
volatile
double
fZ
=
fX
-
1.0
;
if
(
fX
<
1.0
)
if
(
fX
<
1.0
)
{
{
double
fResult
;
double
fResult
;
::
rtl
::
math
::
setNan
(
&
fResult
);
::
rtl
::
math
::
setNan
(
&
fResult
);
...
@@ -1171,10 +1263,13 @@ double SAL_CALL rtl_math_acosh( double fX ) SAL_THROW_EXTERN_C()
...
@@ -1171,10 +1263,13 @@ double SAL_CALL rtl_math_acosh( double fX ) SAL_THROW_EXTERN_C()
}
}
if
(
fX
==
1.0
)
if
(
fX
==
1.0
)
return
0.0
;
return
0.0
;
if
(
fX
<
1.1
)
if
(
fX
<
1.1
)
return
rtl_math_log1p
(
fZ
+
sqrt
(
fZ
*
fZ
+
2.0
*
fZ
));
return
rtl_math_log1p
(
fZ
+
sqrt
(
fZ
*
fZ
+
2.0
*
fZ
));
if
(
fX
<
1.25e7
)
if
(
fX
<
1.25e7
)
return
log
(
fX
+
sqrt
(
fX
*
fX
-
1.0
));
return
log
(
fX
+
sqrt
(
fX
*
fX
-
1.0
));
return
log
(
2.0
*
fX
);
return
log
(
2.0
*
fX
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment