diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2021-11-24 13:43:05 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2021-12-01 14:03:30 +0100 |
commit | c28a13b9e2bd864e8c574d604bcd6da9e93fb476 (patch) | |
tree | c00f9e065e8f62e755bfbf242ff67eb6ef202165 /basic/source/sbx/sbxsng.cxx | |
parent | 25a368c30acb54e0819d2b2b890a3fd1530d8a76 (diff) |
Unify and simplify floating-point-to-integer conversion
* Round the number once, to avoid doing it three times for a successful conversion.
* Round to nearest before convertsToAtMost/convertsToAtLeast, to handle cases like
Dim n As Integer
n = 32767.4
which should succeed.
* Add overflow checks to Hyper (U/Int64) types.
Change-Id: Ib10837e6df3cc1e3aba7a657e882bd40e344fd3b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126173
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'basic/source/sbx/sbxsng.cxx')
-rw-r--r-- | basic/source/sbx/sbxsng.cxx | 78 |
1 files changed, 8 insertions, 70 deletions
diff --git a/basic/source/sbx/sbxsng.cxx b/basic/source/sbx/sbxsng.cxx index a8129b8cd48d..f97c6815d18a 100644 --- a/basic/source/sbx/sbxsng.cxx +++ b/basic/source/sbx/sbxsng.cxx @@ -236,90 +236,28 @@ start: break; } case SbxBYREF | SbxCHAR: - if( !o3tl::convertsToAtMost(o3tl::roundAway(n), SbxMAXCHAR) ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXCHAR; - } - else if( !o3tl::convertsToAtLeast(o3tl::roundAway(n), SbxMINCHAR) ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMINCHAR; - } - *p->pChar = static_cast<sal_Unicode>(n); break; + *p->pChar = ImpDoubleToChar(n); break; case SbxBYREF | SbxBYTE: - if( !o3tl::convertsToAtMost(o3tl::roundAway(n), SbxMAXBYTE) ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXBYTE; - } - else if( n < 0 ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0; - } - *p->pByte = static_cast<sal_uInt8>(n); break; + *p->pByte = ImpDoubleToByte(n); break; case SbxBYREF | SbxINTEGER: case SbxBYREF | SbxBOOL: - if( !o3tl::convertsToAtMost(o3tl::roundAway(n), SbxMAXINT) ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXINT; - } - else if( !o3tl::convertsToAtLeast(o3tl::roundAway(n), SbxMININT) ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMININT; - } - *p->pInteger = static_cast<sal_Int16>(n); break; + *p->pInteger = ImpDoubleToInteger(n); break; case SbxBYREF | SbxERROR: case SbxBYREF | SbxUSHORT: - if( !o3tl::convertsToAtMost(o3tl::roundAway(n), SbxMAXUINT) ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXUINT; - } - else if( n < 0 ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0; - } - *p->pUShort = static_cast<sal_uInt16>(n); break; + *p->pUShort = ImpDoubleToUShort(n); break; case SbxBYREF | SbxLONG: - { - sal_Int32 i; - if( !o3tl::convertsToAtMost(o3tl::roundAway(n), SbxMAXLNG) ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); i = SbxMAXLNG; - } - else if( !o3tl::convertsToAtLeast(o3tl::roundAway(n), SbxMINLNG) ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); i = SbxMINLNG; - } - else - { - i = sal::static_int_cast< sal_Int32 >(n); - } - *p->pLong = i; break; - } + *p->pLong = ImpDoubleToLong(n); break; case SbxBYREF | SbxULONG: - { - sal_uInt32 i; - if( !o3tl::convertsToAtMost(o3tl::roundAway(n), SbxMAXULNG) ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); i = SbxMAXULNG; - } - else if( n < 0 ) - { - SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); i = 0; - } - else - { - i = sal::static_int_cast< sal_uInt32 >(n); - } - *p->pULong = i; break; - } + *p->pULong = ImpDoubleToULong(n); break; case SbxBYREF | SbxSINGLE: *p->pSingle = n; break; case SbxBYREF | SbxDATE: case SbxBYREF | SbxDOUBLE: *p->pDouble = static_cast<double>(n); break; case SbxBYREF | SbxSALINT64: - *p->pnInt64 = static_cast<sal_Int64>(n); break; + *p->pnInt64 = ImpDoubleToSalInt64(n); break; case SbxBYREF | SbxSALUINT64: - *p->puInt64 = static_cast<sal_uInt64>(n); break; + *p->puInt64 = ImpDoubleToSalUInt64(n); break; case SbxBYREF | SbxCURRENCY: double d; if( n > SbxMAXCURR ) |